Skip to content

Commit

Permalink
Condense CFG to DAG and draw it along with liveness
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcere committed Jul 22, 2024
1 parent e7ae1c8 commit 56059ab
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 0 deletions.
Empty file added src/graphs/__init__.py
Empty file.
40 changes: 40 additions & 0 deletions src/graphs/algorithms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
"""
Module that contains useful methods for traversing graphs
"""
from typing import Tuple, List
import networkx as nx


def condense_to_dag(g: nx.Graph) -> Tuple[nx.DiGraph, List[List]]:
"""
Given a graph g, returns another graph such that all the nodes that form a cycle in
the original graph are condense into a single node.
Returns
-------
dag: tuple
a tuple with the directed graph that subsumes the new information and
a list with the corresponding nodes in the original graph for each connected component
"""

# Get the strongly connected components (SCCs)
sccs = list(nx.strongly_connected_components(g))

# Create a new directed graph for the DAG
dag = nx.DiGraph()

# Map each node to its SCC
scc_map = {}
for i, scc in enumerate(sccs):
for node in scc:
scc_map[node] = i

# Add nodes to the DAG, each node represents an SCC
dag.add_nodes_from(range(len(sccs)))

# Add edges between SCCs to form the DAG
for u, v in g.edges():
if scc_map[u] != scc_map[v]:
dag.add_edge(scc_map[u], scc_map[v])

return dag, sccs
12 changes: 12 additions & 0 deletions src/liveness/liveness_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from analysis.fixpoint_analysis import BlockAnalysisInfo, BackwardsAnalysis
from analysis.abstract_state import digraph_from_block_info
from liveness.liveness_state import LivenessState, LivenessBlockInfo
from graphs.algorithms import condense_to_dag
from parser.cfg_block_list import CFGBlockList
from parser.cfg import CFG

Expand Down Expand Up @@ -137,4 +138,15 @@ def dot_from_analysis(cfg: CFG, final_dir: Path = Path(".")) -> Dict[str, Dict[s
renamed_digraph = nx.relabel_nodes(digraph, renaming_dict)

nx.nx_agraph.write_dot(renamed_digraph, final_dir.joinpath(f"{component_name}.dot"))

condensed_digraph, sccs = condense_to_dag(renamed_digraph)

# We just consider the first part of the dot representation ("Block {i}:")
renamed_condensed_dict = {i: '\n'.join(sorted([dot_repr.splitlines()[0] for dot_repr in dot_repr_from_variables]))
for i, dot_repr_from_variables in enumerate(sccs)}

renamed_condensed_digraph = nx.relabel_nodes(condensed_digraph, renamed_condensed_dict)

nx.nx_agraph.write_dot(renamed_condensed_digraph, final_dir.joinpath(f"{component_name}_condensed.dot"))

return results

0 comments on commit 56059ab

Please sign in to comment.