mirror of
https://github.com/KarolS/millfork.git
synced 2024-09-10 11:54:30 +00:00
Lazy flow analysis
This commit is contained in:
parent
b9eb59ad51
commit
a2b6a392a5
@ -8,7 +8,16 @@ import millfork.env.{Label, MemoryAddressConstant, NormalFunction}
|
|||||||
* @author Karol Stasiak
|
* @author Karol Stasiak
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case class FlowInfo(statusBefore: CpuStatus, importanceAfter: CpuImportance, labelUseCountMap: Option[Map[String, Int]]) {
|
class FlowHolder(_statusBefore: () => List[CpuStatus], _importanceAfter: () => List[CpuImportance]) {
|
||||||
|
lazy val statusBefore: List[CpuStatus] = _statusBefore()
|
||||||
|
lazy val importanceAfter: List[CpuImportance] = _importanceAfter()
|
||||||
|
}
|
||||||
|
|
||||||
|
case class FlowInfo(holder: FlowHolder, index: Int, _labelUseCountMap: () => Option[Map[String, Int]]) {
|
||||||
|
|
||||||
|
lazy val statusBefore: CpuStatus = holder.statusBefore(index)
|
||||||
|
lazy val importanceAfter = holder.importanceAfter(index)
|
||||||
|
lazy val labelUseCountMap: Option[Map[String, Int]] = _labelUseCountMap()
|
||||||
|
|
||||||
def hasClear(state: State.Value): Boolean = statusBefore.hasClear(state)
|
def hasClear(state: State.Value): Boolean = statusBefore.hasClear(state)
|
||||||
|
|
||||||
@ -19,35 +28,36 @@ case class FlowInfo(statusBefore: CpuStatus, importanceAfter: CpuImportance, lab
|
|||||||
def labelUseCount(label: String): Int = labelUseCountMap.map(_.getOrElse(label, 0)).getOrElse(-1)
|
def labelUseCount(label: String): Int = labelUseCountMap.map(_.getOrElse(label, 0)).getOrElse(-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
object FlowInfo {
|
|
||||||
val Default = FlowInfo(CpuStatus(), CpuImportance(), None)
|
|
||||||
}
|
|
||||||
|
|
||||||
object FlowAnalyzer {
|
object FlowAnalyzer {
|
||||||
|
|
||||||
|
private val EmptyCpuStatus = CpuStatus()
|
||||||
|
private val EmptyCpuImportance = CpuImportance()
|
||||||
|
|
||||||
def analyze(f: NormalFunction, code: List[AssemblyLine], options: CompilationOptions, req: FlowInfoRequirement.Value): List[(FlowInfo, AssemblyLine)] = {
|
def analyze(f: NormalFunction, code: List[AssemblyLine], options: CompilationOptions, req: FlowInfoRequirement.Value): List[(FlowInfo, AssemblyLine)] = {
|
||||||
val forwardFlow = req match {
|
val forwardFlow = req match {
|
||||||
case FlowInfoRequirement.BothFlows | FlowInfoRequirement.ForwardFlow =>
|
case FlowInfoRequirement.BothFlows | FlowInfoRequirement.ForwardFlow =>
|
||||||
if (options.flag(CompilationFlag.DetailedFlowAnalysis)) {
|
if (options.flag(CompilationFlag.DetailedFlowAnalysis)) {
|
||||||
QuantumFlowAnalyzer.analyze(f, code).map(_.collapse)
|
() => QuantumFlowAnalyzer.analyze(f, code).map(_.collapse)
|
||||||
} else {
|
} else {
|
||||||
CoarseFlowAnalyzer.analyze(f, code)
|
() => CoarseFlowAnalyzer.analyze(f, code)
|
||||||
}
|
}
|
||||||
case FlowInfoRequirement.BackwardFlow | FlowInfoRequirement.JustLabels | FlowInfoRequirement.NoRequirement =>
|
case FlowInfoRequirement.BackwardFlow | FlowInfoRequirement.JustLabels | FlowInfoRequirement.NoRequirement =>
|
||||||
List.fill(code.size)(CpuStatus())
|
() => List.fill(code.size)(EmptyCpuStatus)
|
||||||
}
|
}
|
||||||
val reverseFlow = req match {
|
val reverseFlow = req match {
|
||||||
case FlowInfoRequirement.BothFlows | FlowInfoRequirement.BackwardFlow =>
|
case FlowInfoRequirement.BothFlows | FlowInfoRequirement.BackwardFlow =>
|
||||||
ReverseFlowAnalyzer.analyze(f, code)
|
() => ReverseFlowAnalyzer.analyze(f, code)
|
||||||
case FlowInfoRequirement.ForwardFlow | FlowInfoRequirement.JustLabels | FlowInfoRequirement.NoRequirement =>
|
case FlowInfoRequirement.ForwardFlow | FlowInfoRequirement.JustLabels | FlowInfoRequirement.NoRequirement =>
|
||||||
List.fill(code.size)(CpuImportance())
|
() => List.fill(code.size)(EmptyCpuImportance)
|
||||||
}
|
}
|
||||||
val labelMap = req match {
|
val labelMap: (() => Option[Map[String, Int]]) = () => req match {
|
||||||
case FlowInfoRequirement.NoRequirement => None
|
case FlowInfoRequirement.NoRequirement => None
|
||||||
case _ => Some(code.flatMap {
|
case _ => Some(code.flatMap {
|
||||||
case AssemblyLine(op, _, MemoryAddressConstant(Label(l)), _) if op != Opcode.LABEL => Some(l)
|
case AssemblyLine(op, _, MemoryAddressConstant(Label(l)), _) if op != Opcode.LABEL => Some(l)
|
||||||
case _ => None
|
case _ => None
|
||||||
}.groupBy(identity).mapValues(_.size))
|
}.groupBy(identity).mapValues(_.size))
|
||||||
}
|
}
|
||||||
forwardFlow.zip(reverseFlow).map { case (s, i) => FlowInfo(s, i, labelMap) }.zip(code)
|
val holder = new FlowHolder(forwardFlow, reverseFlow)
|
||||||
|
code.zipWithIndex.map{ case (line, i) => FlowInfo(holder, i, labelMap) -> line}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user