public static (ControlFlowGraph, string) Decompile(ControlFlowGraph graph /*, RecordFunc recordFunc = null*/) { if (graph == null) { throw new ArgumentNullException(nameof(graph)); } var regions = graph.GetAllSeseRegions(); // Do smallest regions first, as they may be nested in a larger one foreach (var(region, regionEntry, regionExit) in regions.OrderBy(x => x.nodes.Count)) { if (regionEntry == graph.EntryIndex) { continue; // Don't try and reduce the 'sequence' of start node -> actual entry point nodes when there's only one entry } /* Func<string> vis = () => // For VS Code debug visualisation * { * var d = graph.ToVis(); * foreach(var n in d.Nodes) * if (region.Contains(int.Parse(n.Id, CultureInfo.InvariantCulture))) * n.Color = "#4040b0"; * return d.ToString(); * }; */ bool containsOther = regions.Any(x => x.nodes != region && !x.nodes.Except(region).Any()); if (containsOther) { continue; } // If either end is a loop header then leave it alone and let the loop rule handle it. if (graph.GetBackEdges().Any(x => x.end == regionEntry || x.end == regionExit)) { continue; } var cut = graph.Cut(region, regionEntry, regionExit); if (cut.Cut.IsCyclic()) // Loop reduction comes later { continue; } return(cut.Merge(ReduceSese(cut.Cut)), Description); } return(graph, null); }