Skip to content

Commit

Permalink
output il cfg
Browse files Browse the repository at this point in the history
  • Loading branch information
ailrst committed Nov 13, 2023
1 parent b7d9a47 commit a6af61e
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/main/scala/cfg_visualiser/DotTools.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ object IDGenerator {
}

def wrap(input: String, width: Integer = 20): String =
return input
if (input.length() <= width) {
input
} else {
Expand Down
53 changes: 53 additions & 0 deletions src/main/scala/ir/IRCursor.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
package ir
import cfg_visualiser.DotElement
import cfg_visualiser.{DotArrow, DotGraph, DotInlineArrow, DotInterArrow, DotIntraArrow, DotNode, DotRegularArrow}

import collection.mutable

/*
Expand Down Expand Up @@ -92,3 +95,53 @@ def computeDomain(prog: Program): mutable.Set[CFGPosition] = {
domain
}


def toDot(prog: Program, labels: Map[CFGPosition, String] = Map.empty) : String = {
val visited : mutable.Set[CFGPosition] = mutable.Set.from(prog.procedures)
var labelcounter = 0

def label(l: Option[String]) = {
l match {
case Some(s) => s
case None =>
labelcounter += 1
s"node$labelcounter"
}
}

val dotNodes = mutable.Map[CFGPosition, DotNode]()
var dotArrows = mutable.ListBuffer[DotArrow]()

val domain = computeDomain(prog)

def nodeText(node: CFGPosition): String = {
var text = node match {
case s: Block => f"[Block] ${s.label}"
case s => s.toString
}
if (labels.contains(node)) {
text += "\n" ++ labels(node)
}
text
}

for (node <- domain) {
node match
case s: Command => dotNodes.addOne(s -> DotNode(label(s.label), nodeText(s)))
case s: Block => dotNodes.addOne(s -> DotNode(label(None), nodeText(s)))
case s => dotNodes.addOne(s -> DotNode(label(None), nodeText(s)))
}

for (node <- domain) {
node match {
case s : Call =>
IntraProcIRCursor.succ(s).foreach(n => dotArrows.addOne(DotInterArrow(dotNodes(s), dotNodes(n))))
case s =>
IntraProcIRCursor.succ(s).foreach(n => dotArrows.addOne(DotIntraArrow(dotNodes(s), dotNodes(n))))
case _ => ()
}
}

val allNodes = dotNodes.values.toList.sortBy(n => n.id)
new DotGraph("CursorCFG", allNodes, dotArrows).toDotString
}
100 changes: 99 additions & 1 deletion src/main/scala/util/RunUtils.scala
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,21 @@ object RunUtils {
case (_, constPropSolver.lattice.sublattice.sublattice.FlatElement.Bot) => None
case z => Some(z)
})
val both = newRes.toSet.intersect(oldRes.toSet)
val notnew = (newRes.toSet).filter(x => !both.contains(x))
val notOld = (oldRes.toSet).filter(x => !both.contains(x))
// newRes and oldRes should have value equality


config.analysisResultsPath.foreach(s => writeToFile(printAnalysisResults(IRProgram, newCPResult, iteration), s"${s}_newconstprop$iteration.txt"))

config.analysisResultsPath.foreach(s => writeToFile(toDot(IRProgram), s"program.dot"))
config.analysisResultsPath.foreach(s => writeToFile(toDot(IRProgram, newCPResult.map((k,v) => (k, v.toString))), s"program-constprop.dot"))

config.analysisDotPath.foreach(s => writeToFile(cfg.toDot(Output.labeler(constPropResult, constPropSolver.stateAfterNode), Output.dotIder), s"${s}_constprop$iteration.dot"))

config.analysisDotPath.foreach(s => writeToFile(cfg.toDot(Output.labeler(constPropResult, constPropSolver.stateAfterNode), Output.dotIder), s"${s}_constprop$iteration.dot"))

config.analysisResultsPath.foreach(s => writeToFile(printAnalysisResults(cfg, constPropResult, iteration), s"${s}_constprop$iteration.txt"))

Logger.info("[!] Running MRA")
Expand Down Expand Up @@ -206,7 +217,94 @@ object RunUtils {
newIR
}

def printAnalysisResults(cfg: ProgramCfg, result: Map[CfgNode, _], iteration: Int): String = {
def printAnalysisResults(cfg: Program, result: Map[IntraProcIRCursor.Node, _], iteration: Int): String = {
val functionEntries = cfg.procedures
val s = StringBuilder()
s.append(System.lineSeparator())
for (f <- functionEntries) {
val stack: mutable.Stack[IntraProcIRCursor.Node] = mutable.Stack()
val visited: mutable.Set[IntraProcIRCursor.Node] = mutable.Set()
stack.push(f)
var previousBlock: String = ""
var isEntryNode = false
while (stack.nonEmpty) {
val next = stack.pop()
if (!visited.contains(next)) {
visited.add(next)
next.match {
case c: Block => printBlock(c)
case c: Call => s.append(System.lineSeparator())
isEntryNode = false
printNode(c)
case c: Command =>
//if (c.parent.label != previousBlock) {
// printBlock(c.parent)
//}
printNode(c)
previousBlock = c.parent.label
isEntryNode = false
case c: Procedure =>
printNode(c)
isEntryNode = true
case _ => isEntryNode = false
}
val successors = IntraProcIRCursor.succ(next)
if (successors.size > 1) {
val successorsCmd = successors.collect { case c: Command => c }.toSeq.sortBy(_.label)
printGoTo(successorsCmd)
for (s <- successorsCmd) {
if (!visited.contains(s)) {
stack.push(s)
}
}
} else if (successors.size == 1) {
val successor = successors.head
if (!visited.contains(successor)) {
stack.push(successor)
}
successor.match {
case c: Command if (c.parent.label != previousBlock) && (!isEntryNode) => printGoTo(Seq(c))
case _ =>
}
}
}
}
s.append(System.lineSeparator())
}

def printNode(node: IntraProcIRCursor.Node): Unit = {
node match {
case _: Statement => s.append("[Stmt] ")
case _: Procedure => s.append("[FunctionEntry] ")
case _: Call => s.append("[Jmp] ")
case _ => ()
}

s.append(node)
s.append(" :: ")
s.append(result(node))
s.append(System.lineSeparator())
}

def printGoTo(nodes: Seq[Command]): Unit = {
s.append("[GoTo] ")
s.append(nodes.map(_.label).mkString(", "))
s.append(System.lineSeparator())
s.append(System.lineSeparator())
}

def printBlock(node: Block): Unit = {
s.append("[Block] ")
s.append(node.label)
s.append(System.lineSeparator())
}


s.toString()
}


def printAnalysisResults(cfg: ProgramCfg, result: Map[CfgNode, _], iteration: Int): String = {
val functionEntries = cfg.nodes.collect { case n: CfgFunctionEntryNode => n }.toSeq.sortBy(_.data.name)
val s = StringBuilder()
s.append(System.lineSeparator())
Expand Down

0 comments on commit a6af61e

Please sign in to comment.