feat: (maybe) tail call optimisation
This commit is contained in:
parent
4fb399a5e1
commit
631f9ddca5
@ -236,13 +236,18 @@ object asmGenerator {
|
|||||||
chain += Jump(LabelArg(startLabel))
|
chain += Jump(LabelArg(startLabel))
|
||||||
chain += LabelDef(endLabel)
|
chain += LabelDef(endLabel)
|
||||||
|
|
||||||
|
case call: microWacc.Call =>
|
||||||
|
chain ++= generateCall(call, isTail = false)
|
||||||
|
|
||||||
case microWacc.Return(expr) =>
|
case microWacc.Return(expr) =>
|
||||||
|
expr match {
|
||||||
|
case call: microWacc.Call =>
|
||||||
|
chain ++= generateCall(call, isTail = true) // tco
|
||||||
|
case _ =>
|
||||||
chain ++= evalExprOntoStack(expr)
|
chain ++= evalExprOntoStack(expr)
|
||||||
chain += stack.pop(RAX)
|
chain += stack.pop(RAX)
|
||||||
chain ++= funcEpilogue()
|
chain ++= funcEpilogue()
|
||||||
|
}
|
||||||
case call: microWacc.Call =>
|
|
||||||
chain ++= generateCall(call)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
chain
|
chain
|
||||||
@ -323,7 +328,7 @@ object asmGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case call: microWacc.Call =>
|
case call: microWacc.Call =>
|
||||||
chain ++= generateCall(call)
|
chain ++= generateCall(call, isTail = false)
|
||||||
chain += stack.push(RAX)
|
chain += stack.push(RAX)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,7 +336,7 @@ object asmGenerator {
|
|||||||
chain
|
chain
|
||||||
}
|
}
|
||||||
|
|
||||||
def generateCall(call: microWacc.Call)(using
|
def generateCall(call: microWacc.Call, isTail: Boolean)(using
|
||||||
stack: Stack,
|
stack: Stack,
|
||||||
strings: ListBuffer[String],
|
strings: ListBuffer[String],
|
||||||
labelGenerator: LabelGenerator
|
labelGenerator: LabelGenerator
|
||||||
@ -348,7 +353,12 @@ object asmGenerator {
|
|||||||
chain ++= evalExprOntoStack(_)
|
chain ++= evalExprOntoStack(_)
|
||||||
}
|
}
|
||||||
|
|
||||||
chain += assemblyIR.Call(LabelArg(labelGenerator.getLabel(target)))
|
// Tail Call Optimisation (TCO)
|
||||||
|
if (isTail) {
|
||||||
|
chain += Jump(LabelArg(labelGenerator.getLabel(target))) // tail call
|
||||||
|
} else {
|
||||||
|
chain += assemblyIR.Call(LabelArg(labelGenerator.getLabel(target))) // regular call
|
||||||
|
}
|
||||||
|
|
||||||
if (args.size > argRegs.size) {
|
if (args.size > argRegs.size) {
|
||||||
chain += stack.drop(args.size - argRegs.size)
|
chain += stack.drop(args.size - argRegs.size)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user