Skip to content

Commit

Permalink
New optimizer
Browse files Browse the repository at this point in the history
  • Loading branch information
ssuukk committed Jun 6, 2020
1 parent 52e1cb1 commit 6c91bb6
Show file tree
Hide file tree
Showing 13 changed files with 1,097 additions and 229 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/build/*
/.gradle/*
/.idea/*
/gradle/*

53 changes: 28 additions & 25 deletions src/main/kotlin/pl/qus/wolin/Main.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import pl.qus.wolin.exception.NoRuleException
import pl.qus.wolin.pl.qus.wolin.StackOpsSanitizer
import pl.qus.wolin.pl.qus.wolin.optimizer.NewOptimizerProcessor
import pl.qus.wolin.pl.qus.wolin.optimizer.OptimizerProcessor
import pl.qus.wolin.pl.qus.wolin.optimizer.testTree
import java.io.*
import java.lang.StringBuilder
import java.net.ServerSocket
Expand Down Expand Up @@ -242,7 +241,8 @@ label xxxx

optimizePseudoAsm(
FileInputStream(File("src/main/wolin/assembler.asm")),
FileOutputStream(File("src/main/wolin/assembler_optX.asm"))
FileOutputStream(File("src/main/wolin/assembler_optX.asm")),
finalState
)

sanitizePseudoAsmStackOps(
Expand All @@ -259,7 +259,6 @@ label xxxx
)

//launch<MyApp>(args)
testTree()
}

private fun sanitizePseudoAsmStackOps(
Expand All @@ -277,33 +276,37 @@ label xxxx

}

private fun optimizePseudoAsm(asmStream: InputStream, outStream: OutputStream) {
private fun optimizePseudoAsm(
asmStream: InputStream,
outStream: OutputStream,
finalState: WolinStateObject
) {
val asmLexer = PseudoAsmLexer(ANTLRInputStream(asmStream))
val asmTokens = CommonTokenStream(asmLexer)
val asmParser = PseudoAsmParser(asmTokens)
val asmContext = asmParser.pseudoAsmFile()
val optimizer = OptimizerProcessor()
val newOpt = NewOptimizerProcessor()


newOpt.findRednundantRegs(asmContext)


// zebrać wszystkie rejestry
optimizer.gatherAllSPRegs(asmContext)
// sprawdzić które kwalifikują się do usunięcia
optimizer.markSingleAssignmentRegs(asmContext)
// tu można wygenerować ponownie plik tekstowy, pewnie nawet trzeba, tu się przesuwa funkcyjne rejestry
optimizer.replaceSingleAssignmentRegWithItsValue(asmContext)
// sprawdzić, czy dany rejestr występuje tylko jako free/alloc +ew. let rejestr =, tylko odflaguje
optimizer.markRegIfStillUsed(asmContext)
// usuwa oflagowane rejestry
optimizer.removeAndShiftArgs(asmContext)

optimizer.optimizeReverseAssigns(asmContext)
optimizer.replaceSingleAssignmentRegWithItsValue(asmContext)
optimizer.markRegIfStillUsed(asmContext)
optimizer.removeAndShiftArgs(asmContext)
val newOpt = NewOptimizerProcessor(finalState)
newOpt.buildFlowTree(asmContext)
//newOpt.replaceRedundantRemoveAllocs(asmContext, finalState)
newOpt.removeIdentities(asmContext)


// // zebrać wszystkie rejestry
// optimizer.gatherAllSPRegs(asmContext)
// // sprawdzić które kwalifikują się do usunięcia
// optimizer.markSingleAssignmentRegs(asmContext)
// // tu można wygenerować ponownie plik tekstowy, pewnie nawet trzeba, tu się przesuwa funkcyjne rejestry
// optimizer.replaceSingleAssignmentRegWithItsValue(asmContext)
// // sprawdzić, czy dany rejestr występuje tylko jako free/alloc +ew. let rejestr =, tylko odflaguje
// optimizer.markRegIfStillUsed(asmContext)
// // usuwa oflagowane rejestry
// optimizer.removeAndShiftArgs(asmContext)
//
// optimizer.optimizeReverseAssigns(asmContext)
// optimizer.replaceSingleAssignmentRegWithItsValue(asmContext)
// optimizer.markRegIfStillUsed(asmContext)
// optimizer.removeAndShiftArgs(asmContext)


optimizer.sanitizeDerefs(asmContext)
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/pl/qus/wolin/PseudoAsmVisitor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ let SP(?a)[uword] = SP(?b)[uword]
}

if(template.instrukcja().text == "string" && state.matched != null) {
println("tu!")
println("tu string!")
}


Expand Down
1 change: 1 addition & 0 deletions src/main/kotlin/pl/qus/wolin/StackOpsSanitizer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class StackOpsSanitizer(outStream: OutputStream) {

private val writer = outStream.bufferedWriter()


fun startWork(ctx: PseudoAsmParser.PseudoAsmFileContext) {
val i = ctx.linia()?.iterator()

Expand Down
7 changes: 5 additions & 2 deletions src/main/kotlin/pl/qus/wolin/WolinStateObject.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class WolinStateObject(val pass: Pass) {
var codeOn = true
var commentOn = true

private var variablary = hashMapOf<String, Zmienna>()
var variablary = hashMapOf<String, Zmienna>()
var functiary = hashMapOf<String, Funkcja>()
private var classary = hashMapOf<String, Klasa>()

Expand Down Expand Up @@ -383,7 +383,10 @@ class WolinStateObject(val pass: Pass) {
}

fun varToAsm(register: Zmienna, deref: RegOper = RegOper.VALUE): String {
val finalDeref = if(deref == RegOper.STAR && register.type.isPointer) RegOper.VALUE else deref
val finalDeref =
if(deref == RegOper.STAR && register.type.isPointer) RegOper.VALUE
else if(deref == RegOper.AMPRESAND && !register.type.isPointer) RegOper.VALUE
else deref

return when (finalDeref) {
RegOper.AMPRESAND -> "&"
Expand Down
147 changes: 72 additions & 75 deletions src/main/kotlin/pl/qus/wolin/optimizer/FlowNode.kt
Original file line number Diff line number Diff line change
@@ -1,91 +1,88 @@
package pl.qus.wolin.pl.qus.wolin.optimizer

import org.antlr.v4.runtime.ParserRuleContext
import pl.qus.wolin.WolinStateObject
import pl.qus.wolin.components.FieldType

class DestPair(
var node: FlowNode,
var ref: String
)

{
override fun toString(): String {
return "${ref?:""}${node.contents?.getUid()}"
}
}
class FlowNode (
//var thiz: Register? = null,
var left: FlowNode? = null,
var right: FlowNode? = null,
var leftRef: String = "",
var rightRef: String = "",
var canBeRemoved: Boolean = false,
var contents: ParserRuleContext? = null
var contents: ParserRuleContext? = null,

var incomingLeft: DestPair? = null,
var incomingRight: DestPair? = null,
var goesInto: MutableList<DestPair> = mutableListOf(),

var referenced: Boolean = false,
var opcode: String = "",
var nodeNum: Int = 0,
var type: Type = Type.NODE,
var redundant: Boolean = false
) {
val hasNoSources get() = left == null
val leftAggregates get() = left?.left != null && left?.right != null
val rightAggregates get() = right?.left != null && right?.right != null
enum class Type {ENTRY, EXIT, NODE}

val isSimple get() = incomingRight == null
val isNode get() = type == Type.NODE
val isNotEntry get() = type != Type.ENTRY
val isEntry get() = type == Type.ENTRY
val leftIsComplex get() = incomingLeft?.node?.incomingLeft != null && incomingLeft?.node?.incomingRight != null
val rightIsComplex get() = incomingRight?.node?.incomingLeft != null && incomingRight?.node?.incomingRight != null
val uid get() = contents?.getUid()



override fun toString(): String {
return "${contents?.text} <- ${left?.contents?.text} + ${right?.contents?.text}"
return "'${contents!!.getUid()}' ${type.name} re'd=$referenced ${contents?.text} <- ${incomingLeft?.node?.contents?.text} + ${incomingRight?.node?.contents?.text}"
}

fun deepLeft(): FlowNode? {
return when {
hasNoSources -> {
canBeRemoved = false
this // tylko źródłowy nołd nie ma src
}
leftRef != "" -> {
canBeRemoved = false
left // jest referencja, nie da się
}
leftAggregates -> {
left?.canBeRemoved = false
left // koniec, powyżej nołd agregujący
}
else -> {
canBeRemoved = true
left!!.deepLeft()
}
fun walkDownToSource(finalState: WolinStateObject) {

val leftKnowsAboutMe = incomingLeft?.node?.goesInto?.any {
it.node.contents!!.getUid() == this.contents!!.getUid()
}
}

fun deepRight(): FlowNode? {
return when {
hasNoSources -> {
canBeRemoved = false
this // tylko źródłowy nołd nie ma src
}
rightRef != "" -> {
canBeRemoved = false
left // jest referencja, nie da się
}
rightAggregates -> {
right?.canBeRemoved = false
right // koniec, powyżej nołd agregujący
}
right == null -> {
null
}
else -> {
canBeRemoved = true
right!!.deepLeft()
}
if(leftKnowsAboutMe != true) {
val toMe = DestPair(this, this.incomingLeft?.ref ?: "")
incomingLeft?.node?.goesInto?.add(toMe)
}
}

}
val rightKnowsAboutMe = incomingRight?.node?.goesInto?.any {
it.node.contents!!.getUid() == this.contents!!.getUid()
}

if(rightKnowsAboutMe != true) {
val toMe = DestPair(this, this.incomingRight?.ref ?: "")
incomingRight?.node?.goesInto?.add(toMe)
}

val meInVariablary = finalState.variablary.values.firstOrNull { it.name == this.contents!!.getUid() }

// if(incomingLeft != null) {
// type = Type.NODE
// }

if(contents?.text?.contains("__returnValue") == true) {
type = Type.EXIT
}

if(meInVariablary?.fieldType == FieldType.ARGUMENT) {
type = Type.ENTRY
}

if(incomingLeft == null && incomingRight == null) {
type = Type.ENTRY
} else {
incomingLeft!!.node.walkDownToSource(finalState)
incomingRight?.node?.walkDownToSource(finalState)
}
}
}

fun testTree() {
// val what = FlowNode(Register(name="what"), null, null)
// val imm0 = FlowNode(Register(name="#0"), null, null)
// val r3 = FlowNode(Register(name="r3"), what, null)
// val r4 = FlowNode(Register(name="r4"), imm0, null)
// val r2 = FlowNode(Register(name="r2"), r3, r4)
// val r1 = FlowNode(Register(name="r1"), r2, null)
// val ret = FlowNode(Register(name="ret"), r1, null, "&")
//
// val regs = listOf(what, imm0, r3, r4, r2, r1, ret)
//
// val lewyDlaR2 = r2.deepLeft()
// val prawyDlaR2 = r2.deepRight() //
// val dlaRet = ret.deepLeft() // argument można zastąpić...
// val dlaR1 = r1.deepLeft() // r1 można zastąpić...
//
// regs.filter { it.thiz?.canBeRemoved == true }.forEach {
// println("Mozna usunac: ${it.thiz?.name}, zastępując jego wystąpienia: ${it.deepLeft()?.thiz?.name}")
// }
//
// println("tu!")
}
Loading

0 comments on commit 6c91bb6

Please sign in to comment.