public (DirectedGraph <Region>, Region) Build() { foreach (var b in proc.ControlGraph.Blocks) { if (b.Pred.Count == 0 && b != proc.EntryBlock || b == proc.ExitBlock) { continue; } var reg = regionFactory.Create(b); btor.Add(b, reg); graph.AddNode(reg); } foreach (var b in proc.ControlGraph.Blocks) { if (btor.TryGetValue(b, out var reg) && reg.Type == RegionType.IncSwitch) { MakeSwitchPads(b); } } foreach (var b in proc.ControlGraph.Blocks) { if (b.Pred.Count == 0 && b != proc.EntryBlock) { continue; } btor.TryGetValue(b, out var from); foreach (var s in b.Succ) { if (s == proc.ExitBlock) { continue; } var to = Destination(b, s); graph.AddEdge(from, to); } if (from != null) { if (graph.Successors(from).Count == 0) { from.Type = RegionType.Tail; } } } foreach (var reg in graph.Nodes.ToList()) { if (graph.Predecessors(reg).Count == 0 && reg != btor[proc.EntryBlock]) { graph.Nodes.Remove(reg); } } return(graph, btor[proc.EntryBlock]);
/// <summary> /// Builds a graph of regions based on the basic blocks of the code. /// </summary> /// <param name="proc"></param> /// <returns></returns> public Tuple<DirectedGraph<Region>, Region> BuildRegionGraph(Procedure proc) { var btor = new Dictionary<Block, Region>(); var regs = new DiGraph<Region>(); var regionFactory = new RegionFactory(); foreach (var b in proc.ControlGraph.Blocks) { if (b.Pred.Count == 0 && b != proc.EntryBlock || b == proc.ExitBlock) continue; var reg = regionFactory.Create(b); btor.Add(b, reg); regs.AddNode(reg); } foreach (var b in proc.ControlGraph.Blocks) { if (b.Pred.Count == 0 && b != proc.EntryBlock) continue; Region from; btor.TryGetValue(b, out from); foreach (var s in b.Succ) { if (s == proc.ExitBlock) continue; var to = btor[s]; regs.AddEdge(from, to); } if (from != null) { if (regs.Successors(from).Count == 0) from.Type = RegionType.Tail; } } foreach (var reg in regs.Nodes.ToList()) { if (regs.Predecessors(reg).Count == 0 && reg != btor[proc.EntryBlock]) { regs.Nodes.Remove(reg); } } return new Tuple<DirectedGraph<Region>, Region>(regs, btor[proc.EntryBlock]); }