mirror of
https://github.com/irmen/prog8.git
synced 2025-02-25 04:29:36 +00:00
move IR optimizer to IR Codegen module
This commit is contained in:
parent
b4352ad38b
commit
ab00822764
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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,
|
@ -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
|
||||
}
|
@ -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({
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user