Skip to content

Commit

Permalink
Implement conditional purity analysis, improve stats
Browse files Browse the repository at this point in the history
  • Loading branch information
colder committed Jul 4, 2012
1 parent 28a3cce commit 22faed9
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 21 deletions.
47 changes: 35 additions & 12 deletions src/insane/alias/PointToAnalysis.scala
Expand Up @@ -17,14 +17,16 @@ trait PointToAnalysis extends PointToGraphsDefs with PointToEnvs with PointToLat
import global._
import PointToGraphs._

object PTAnalysisModes extends Enumeration {
val PreciseAnalysis = Value("PreciseAnalysis")
val BluntAnalysis = Value("BluntAnalysis")
val ReductionAnalysis = Value("ReductionAnalysis")
sealed abstract class PTAnalysisModes {

}

type AnalysisMode = PTAnalysisModes.Value
import PTAnalysisModes._
object PreciseAnalysis extends PTAnalysisModes
object BluntAnalysis extends PTAnalysisModes
object ReductionAnalysis extends PTAnalysisModes
object ConditionalAnalysis extends PTAnalysisModes

type AnalysisMode = PTAnalysisModes


class PointToAnalysisPhase extends SubPhase {
Expand Down Expand Up @@ -296,7 +298,7 @@ trait PointToAnalysis extends PointToGraphsDefs with PointToEnvs with PointToLat

reporter.decIndent()

fun.flatPTCFGs += sig -> oldCFG
fun.flatPTCFGs += sig -> oldCFG
fun.flatPTCFGsTime += sig -> (fun.flatPTCFGsTime(sig) + (System.currentTimeMillis - tStart))

settings.ifDebug {
Expand Down Expand Up @@ -476,6 +478,11 @@ trait PointToAnalysis extends PointToGraphsDefs with PointToEnvs with PointToLat
val targetsToConsider = targets.groupBy(_.sym).map{ case (sym, urs) => UnresolvedTargetInfo(sym, urs.map(_.sig).reduce(_ combine _)) }.toSet.filter(t => !excludedTargets(t.sym))

analysisMode match {
case ConditionalAnalysis =>
// In this mode, we always find one target, the pure method
// corresponding to aam.meth, we will inline it in a blunt fashion
Left(Set(ResolvedTargetInfo(buildPureEffect(aam.meth), TypeSignature.fromDeclaration(aam.meth))), BluntAnalysis)

case PreciseAnalysis =>
if (targets.isEmpty) {
Right("no target could be found", true, true)
Expand Down Expand Up @@ -2157,13 +2164,29 @@ trait PointToAnalysis extends PointToGraphsDefs with PointToEnvs with PointToLat
workList = fun :: workList
} else {
// Finished analyzing fun
numberAnalyzed += 1

if (cfgAfter.isFlat && cfgAfter.isPure) {
lastPures.append(fun.symbol)
numberPure += 1
resultsStats.total += 1

val category = if (cfgAfter.isFlat) {
if (cfgAfter.isTop) {
resultsStats.top +=1
"top "
} else if (cfgAfter.isBottom) {
resultsStats.bot +=1
"bottom "
} else if (cfgAfter.isPure) {
resultsStats.pure +=1
"pure "
} else {
resultsStats.impure +=1
"impure "
}
} else {
resultsStats.condImpure +=1
"condImpure"
}

lastResults.append((fun.symbol, category))

ptProgressBar.tick
ptProgressBar.draw()
}
Expand Down
8 changes: 7 additions & 1 deletion src/insane/alias/PointToEnvs.scala
Expand Up @@ -773,7 +773,13 @@ trait PointToEnvs extends PointToGraphsDefs {
}
}

val nodesGrouped: Map[DupNodeID, Set[Node]] = ptGraph.V.filter(n => n.isInstanceOf[INode] || n.isInstanceOf[LNode]).groupBy(DupNode.fromNode _)
def groupingCandidate(n: Node): Boolean = n match {
case _: INode => true
case LNode(from, _, _, _) if from != GBNode => true
case _ => false
}

val nodesGrouped: Map[DupNodeID, Set[Node]] = ptGraph.V.filter(groupingCandidate).groupBy(DupNode.fromNode _)

var newEnv = this

Expand Down
7 changes: 5 additions & 2 deletions src/insane/alias/PointToGraphsDefs.scala
Expand Up @@ -325,16 +325,19 @@ trait PointToGraphsDefs {
def pureEffectBuilder(ctx: (FunctionCFG, PTEnv)) = {
val (cfg, env) = ctx

var newEnv = env
val retval = cfg.retval

val retInfo = TypeInfo.subtypeOf(retval.tpe)
val retNode = if (isGroundTypeInfo(retInfo)) {
typeToLitNode(retval.tpe)
} else {
INode(NoUniqueID, false, cfg.retval.tpe.typeSymbol)
val lnode = LNode(GBNode, NoField, NoUniqueID, SigEntry.fromTypeInfo(retInfo))
newEnv = newEnv.addOEdge(GBNode, NoField, lnode)
lnode
}

val newEnv = env.addNode(retNode).setL(retval, Set(retNode))
newEnv = newEnv.addNode(retNode).setL(retval, Set(retNode))

(cfg, newEnv)
}
Expand Down
23 changes: 17 additions & 6 deletions src/insane/utils/Context.scala
Expand Up @@ -97,10 +97,17 @@ trait Context {
var analysisStack = Stack[AnalysisContext]()
var currentContext: AnalysisContext = null

var lastPures = new RingBuffer[Symbol](10)
var lastResults = new RingBuffer[(Symbol, String)](10)

var numberPure = 0
var numberAnalyzed = 0
case class ResultStats(var pure: Int = 0,
var impure: Int = 0,
var condPure: Int = 0,
var condImpure: Int = 0,
var bot: Int = 0,
var top: Int = 0,
var total: Int = 0)

var resultsStats = ResultStats()

def dumpAnalysisStack() {
println(" ** Dumping Analysis Stacktrace: **")
Expand All @@ -118,10 +125,14 @@ trait Context {
debugOutput.println(str)
}

o("#pure/#analyzed: "+numberPure+"/"+numberAnalyzed)
def n(i: Integer) = {
String.format("%4d", i)
}

o("#P: "+n(resultsStats.pure)+" | #IP: "+n(resultsStats.impure)+" | #CP: "+n(resultsStats.condPure)+" | #CIP: "+n(resultsStats.condImpure)+" | #B: "+n(resultsStats.bot)+" | #T: "+n(resultsStats.top)+" | #T: "+n(resultsStats.total))

for (sym <- lastPures.contents) {
o(" -> "+uniqueFunctionName(sym))
for ((sym, result) <- lastResults.contents) {
o(" -> ["+result+"] "+uniqueFunctionName(sym))
}

//o("Detected as recursive: ")
Expand Down

0 comments on commit 22faed9

Please sign in to comment.