<s> import time <EOL> def reachableInstructions ( rootInstruction ) : <EOL> instructions = set ( ) <EOL> hashes = set ( ) <EOL> toCheck = [ rootInstruction ] <EOL> while toCheck : <EOL> i = toCheck . pop ( ) <EOL> if i not in instructions : <EOL> instructions . add ( i ) <EOL> hashes . add ( i . hash ) <EOL> for index in range ( i . flowsToCount ( ) ) : <EOL> toCheck . append ( i . flowsTo ( index ) ) <EOL> return instructions <EOL> def groupInstructionsByGraph ( instructions ) : <EOL> graphDict = { } <EOL> for i in instructions : <EOL> graph = i . graph <EOL> if graph not in graphDict : <EOL> graphDict [ graph ] = set ( ) <EOL> graphDict [ graph ] . add ( i ) <EOL> return graphDict <EOL> def drawInstructionGraph ( instructions ) : <EOL> import networkx as nx <EOL> import matplotlib . pyplot as plt <EOL> print "<STR_LIT>" , len ( instructions ) <EOL> g = nx . DiGraph ( ) <EOL> def sizeForNode ( i ) : <EOL> if i . isRootInstruction ( ) : <EOL> return <NUM_LIT> <EOL> else : <EOL> return <NUM_LIT:100> <EOL> edgesToDraw = set ( ) <EOL> nodesToDraw = set ( ) <EOL> nodeColors = { } <EOL> nodeSizes = { } <EOL> def setNodeProps ( i ) : <EOL> if i . getTypedJumpTarget ( ) is not None : <EOL> nodeColors [ i ] = '<STR_LIT>' <EOL> elif i . getInstructionGroup ( ) . needsInterrupt ( i ) : <EOL> nodeColors [ i ] = '<STR_LIT>' <EOL> if i . instructionBody . isJump ( ) : <EOL> nodeSizes [ i ] = <NUM_LIT:100> <EOL> if i not in instructions : <EOL> nodeColors [ i ] = '<STR_LIT>' <EOL> nodeSizes [ i ] = <NUM_LIT:100> <EOL> def addEdge ( i1 , i2 ) : <EOL> clusteringWeight = <NUM_LIT> <EOL> edgeWeight = <NUM_LIT> <EOL> nodesToDraw . add ( i1 ) <EOL> nodesToDraw . add ( i2 ) <EOL> edgesToDraw . add ( ( i1 , i2 ) ) <EOL> addRoots = i2 in instructions <EOL> g . add_node ( i1 ) <EOL> g . add_node ( i2 ) <EOL> g . add_edge ( i1 , i2 , weight = edgeWeight ) <EOL> if addRoots : <EOL> g . add_node ( i1 . rootInstruction ( ) ) <EOL> g . add_node ( i2 . rootInstruction ( ) ) <EOL> g . add_edge ( i1 . rootInstruction ( ) , i2 . rootInstruction ( ) , weight = <NUM_LIT:1.0> ) <EOL> g . add_edge ( i1 , i1 . rootInstruction ( ) , weight = clusteringWeight ) <EOL> g . add_edge ( i1 . rootInstruction ( ) , i1 , weight = clusteringWeight ) <EOL> g . add_edge ( i2 , i2 . rootInstruction ( ) , weight = clusteringWeight ) <EOL> g . add_edge ( i2 . rootInstruction ( ) , i2 , weight = clusteringWeight ) <EOL> setNodeProps ( i1 ) <EOL> setNodeProps ( i2 ) <EOL> for i in instructions : <EOL> for ix in range ( i . flowsToCount ( ) ) : <EOL> flowsTo = i . flowsTo ( ix ) <EOL> addEdge ( <EOL> i , <EOL> flowsTo <EOL> ) <EOL> pos = nx . spectral_layout ( g ) <EOL> nx . draw_networkx_nodes ( <EOL> g , <EOL> pos , <EOL> nodelist = [ n for n in g . nodes ( ) if n in nodesToDraw ] , <EOL> with_labels = False , <EOL> node_size = [ nodeSizes [ n ] if n in nodeSizes else <NUM_LIT> for n in g . nodes ( ) ] , <EOL> node_color = [ nodeColors [ n ] if n in nodeColors else '<STR_LIT>' for n in g . nodes ( ) ] , <EOL> alpha = <NUM_LIT> <EOL> ) <EOL> nx . draw_networkx_edges ( <EOL> g , <EOL> pos , <EOL> edgelist = [ e for e in g . edges ( ) if e in edgesToDraw ] , <EOL> alpha = <NUM_LIT> <EOL> ) <EOL> plt . show ( ) <EOL> def checkInstructionGraphCycles ( instructions ) : <EOL> import networkx as nx <EOL> g = nx . DiGraph ( ) <EOL> for i in instructions : <EOL> g . add_node ( i ) <EOL> for ix in range ( i . flowsToCount ( ) ) : <EOL> flowsTo = i . flowsTo ( ix ) <EOL> if flowsTo in instructions : <EOL> g . add_edge ( i , flowsTo ) <EOL> cycles = nx . simple_cycles ( g ) <EOL> for c in cycles : <EOL> if not checkCycleHasEntrypoint ( c ) : <EOL> print "<STR_LIT>" <EOL> print "<STR_LIT>" <EOL> for i in c : <EOL> print i <EOL> print "<STR_LIT>" <EOL> for sub in i . children ( ) : <EOL> print "<STR_LIT:\t>" , repr ( sub ) <EOL> print "<STR_LIT>" <EOL> else : <EOL> print "<STR_LIT>" <EOL> print "<STR_LIT>" , len ( c ) , "<STR_LIT>" <EOL> for i in c : <EOL> if i . getTypedJumpTarget ( ) : <EOL> print "<STR_LIT>" , <EOL> else : <EOL> print "<STR_LIT:U+0020>" , <EOL> print repr ( i ) <EOL> print "<STR_LIT>" <EOL> def checkCycleHasEntrypoint ( c ) : <EOL> for i in c : <EOL> if i . getTypedJumpTarget ( ) : <EOL> return True <EOL> return False <EOL> def allInstructionsOfAllVersions ( instructionGraph , name ) : <EOL> allGraphs = instructionGraph . graphs <EOL> graphs = [ g for g in allGraphs if g . graphName == name ] <EOL> allInstructions = set ( ) <EOL> def add ( n ) : <EOL> if n in allInstructions : <EOL> return <EOL> allInstructions . add ( n ) <EOL> for s in n . children ( ) : <EOL> add ( s ) <EOL> print "<STR_LIT>" , len ( graphs ) , "<STR_LIT>" , name <EOL> for g in graphs : <EOL> entryNode = instructionGraph . getRootInstruction ( g , None ) <EOL> reachable = reachableInstructions ( entryNode ) <EOL> for n in reachable : <EOL> add ( n ) <EOL> return allInstructions <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> import fora <EOL> fora . init_local ( ) <EOL> i = fora . eval ( '<STR_LIT>' ) <EOL> if <NUM_LIT:1> : <EOL> print "<STR_LIT>" <EOL> t0 = time . time ( ) <EOL> fora . eval ( '<STR_LIT>' ) <EOL> print "<STR_LIT>" , time . time ( ) - t0 <EOL> instructions = reachableInstructions ( i ) <EOL> graphs = groupInstructionsByGraph ( instructions ) <EOL> graphsByName = dict ( [ ( g . graphName , g ) for g in graphs ] ) <EOL> print len ( instructions ) , "<STR_LIT>" <EOL> print len ( graphs ) , "<STR_LIT>" <EOL> allSumInstructions = allInstructionsOfAllVersions ( i . instructionGraph , '<STR_LIT>' ) <EOL> checkInstructionGraphCycles ( allSumInstructions ) </s>
