public void Dump(string caption) { return; // This is horribly verbose, so only use it when debugging unit tests. Debug.Print("== {0} =====================", caption); Debug.Print("{0} nodes", G.Nodes.Count); foreach (var block in G.Nodes.OrderBy(n => n)) { Debug.Print("{0}: // pred: {1}", block, string.Join(" ", G.Successors(block) .OrderBy(n => n))); RtlInstructionCluster cluster; if (!sr.Instructions.TryGetValue(block, out cluster)) { Debug.Print(" *****"); } else { Debug.Print(" {0}", cluster); foreach (var instr in cluster.Instructions) { Debug.Print(" {0}", instr); } } Debug.Print(" // succ: {0}", string.Join(" ", G.Predecessors(block) .OrderBy(n => n))); } }
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]); }
public void Dump(string caption = "Dump") { //BreakOnWatchedAddress(ICFG.Nodes.Select(n => n.Address)); return; // This is horribly verbose, so only use it when debugging unit tests. #if VERBOSE Debug.Print("== {0} =====================", caption); Debug.Print("{0} nodes", ICFG.Nodes.Count); foreach (var block in ICFG.Nodes.OrderBy(n => n.Address)) { var addrEnd = block.GetEndAddress(); if (KnownProcedures.Contains(block.Address)) { Debug.WriteLine(""); Debug.Print("-- {0}: known procedure ----------", block.Address); } else if (DirectlyCalledAddresses.ContainsKey(block.Address)) { Debug.WriteLine(""); Debug.Print("-- {0}: possible procedure, called {1} time(s) ----------", block.Address, DirectlyCalledAddresses[block.Address]); } Debug.Print("{0}: // pred: {1}", block.Name, string.Join(" ", ICFG.Predecessors(block) .OrderBy(n => n.Address) .Select(n => n.Address))); foreach (var cluster in block.Instructions) { Debug.Print(" {0}", cluster); foreach (var instr in cluster.Instructions) { Debug.Print(" {0}", instr); } } Debug.Print(" // succ: {0}", string.Join(" ", ICFG.Successors(block) .OrderBy(n => n.Address) .Select(n => n.Address))); } #endif }