public void RewriteBasicBlocks() { foreach (var proc in procedures) { SetInitialValueOfStackPointer(proc); var blocks = new DfsIterator <Block>(proc.ControlGraph).PreOrder().ToList(); foreach (var block in blocks) { RewriteBlock(block); } } }
/// <summary> /// Executes the core of the analysis /// </summary> /// <remarks> /// The algorithm visits nodes in post-order in each iteration. This /// means that all descendants of a node will be visited (and /// hence had the chance to be reduced) before the node itself. /// The algorithm’s behavior when visiting node _n_ /// depends on hether the region at _n_ /// is acyclic (has no loop) or not. For an acyclic region, the /// algorithm tries to match the subgraph /// at _n_to an acyclic schemas (3.2). If there is no match, /// and the region is a switch candidate, then it attempts to /// refine the region at _n_ into a switch region. /// /// If _n_ is cyclic, the algorithm /// compares the region at _n_ to the cyclic schemata. /// If this fails, it refines _n_ into a loop (3.6). /// /// If both matching and refinement do not make progress, the /// current node _n_ is then skipped for the current iteration of /// the algorithm. If there is an iteration in which all /// nodes are skipped, i.e., the algorithm makes no progress, then /// the algorithm employs a last resort refinement (3.7) to /// ensure that progress can be made in the next iteration. /// </remarks> public Region Execute() { var result = BuildRegionGraph(proc); this.regionGraph = result.Item1; this.entry = result.Item2; int iterations = 0; int oldCount; int newCount; do { ++iterations; if (iterations > 1000) { eventListener.Warn( eventListener.CreateProcedureNavigator(program, proc), "Structure analysis stopped making progress, quitting. Please report this issue at https://github.com/uxmal/reko"); DumpGraph(); break; } //if (proc.Name.EndsWith()) oldCount = regionGraph.Nodes.Count; this.doms = new DominatorGraph<Region>(this.regionGraph, result.Item2); this.unresolvedCycles = new Queue<Tuple<Region, ISet<Region>>>(); this.unresolvedNoncycles = new Queue<Tuple<Region, ISet<Region>>>(); var postOrder = new DfsIterator<Region>(regionGraph).PostOrder(entry).ToList(); bool didReduce = false; foreach (var n in postOrder) { Probe(); didReduce = false; do { didReduce = ReduceAcyclic(n); if (!didReduce && IsCyclic(n)) { didReduce = ReduceCyclic(n); } } while (didReduce); } newCount = regionGraph.Nodes.Count; if (newCount == oldCount && newCount > 1) { // Didn't make any progress this round, // try refining unstructured regions ProcessUnresolvedRegions(); } } while (regionGraph.Nodes.Count > 1); return entry; }
public Region Execute(Procedure proc) { #if NILZ We focus on the novel aspects of our algorithm in this paper and refer readers interested in any structural analysis details elided to standard sources Like vanilla structural analysis, our algorithm visits nodes in post-order in each iteration. Intuitively, this means that all descendants of a node will be visited (and hence had the chance to be reduced) before the node itself. The algorithm’s behavior when visiting node _n_ depends on hether the region at _n_ is acyclic (has no loop) or not. For an acyclic region, the algorithm tries to match the subgraph at _n_to an acyclic schemas (3.2). If there is no match, and the region is a switch candidate, then it attempts to refine the region at _n_ into a switch region (3.4). If _n_ is cyclic, the algorithm compares the region at _n_ to the cyclic schemas (3.5) If this fails, it refines _n_ into a loop (3.6). If both matching and refinement do not make progress, the current node _n_ is then skipped for the current iteration of the algorithm. If there is an iteration in which all nodes are skipped, i.e., the algorithm makes no progress, then the algorithm employs a last resort refinement (3.7) to ensure that progress can be made in the next iteration. #endif var result = BuildRegionGraph(proc); this.regionGraph = result.Item1; var entry = result.Item2; DumpGraph(); newGraph = new DiGraph<Region>(); do { this.Changed = false; this.doms = new DominatorGraph<Region>(this.regionGraph, result.Item2); this.unresolvedCycles = new List<Tuple<Region, ISet<Region>>>(); var postOrder = new DfsIterator<Region>(regionGraph).PostOrder(entry).ToList(); Debug.Print("Iterating...."); DumpGraph(); foreach (var n in postOrder) { entry = Dfs(n); } } while (Changed); return entry; }
/// <summary> /// Trace the reachable blocks using DFS; call them 'reachable'. /// </summary> /// <returns>A set of blocks considered "valid".</returns> private HashSet <RtlBlock> TraceReachableBlocks(IEnumerable <Address> procstarts) { var reachable = new HashSet <RtlBlock>(); var mpAddrToBlock = blocks.Nodes.ToDictionary(k => k.Address); foreach (var addrProcStart in procstarts) { if (mpAddrToBlock.TryGetValue(addrProcStart, out var entry)) { var r = new DfsIterator <RtlBlock>(blocks).PreOrder(entry).ToHashSet(); reachable.UnionWith(r); } } return(reachable); }
public void BuildNodes() { int bId = 0; var iterator = new DfsIterator <Block>(proc.ControlGraph); foreach (Block b in iterator.PreOrder(proc.EntryBlock)) { var cfgNode = new StructureNode(b, ++bId); nodeList.Add(cfgNode); blockNodes.Add(b, cfgNode); } if (!blockNodes.ContainsKey(proc.ExitBlock)) { var cfgNode = new StructureNode(proc.ExitBlock, ++bId); nodeList.Add(cfgNode); blockNodes.Add(proc.ExitBlock, cfgNode); } }
private void WriteCode(Procedure proc) { BlockGraph graph = proc.ControlGraph; DfsIterator <Block> iterator = new DfsIterator <Block>(graph); foreach (Block block in new DfsIterator <Block>(graph).PreOrder(proc.EntryBlock)) { if (ShouldIgnoreBlock(proc, block)) { continue; } writer.WriteLine(); EmitLabel(block); foreach (Statement stm in block.Statements) { stm.Instruction.Accept(this); } } }
public bool ProcessUnresolvedRegions() { if (unresolvedCycles.Count != 0) { var cycle = unresolvedCycles.Dequeue(); RefineLoop(cycle.Item1, cycle.Item2); return true; } var postOrder = new DfsIterator<Region>(regionGraph).PostOrder(entry).ToList(); foreach (var n in postOrder) { if (CoalesceTailRegion(n, regionGraph.Nodes)) return true; } foreach (var n in postOrder) { if (LastResort(n)) return true; } return false; }
/// <summary> /// Executes the core of the analysis /// </summary> /// <remarks> /// The algorithm visits nodes in post-order in each iteration. This /// means that all descendants of a node will be visited (and /// hence had the chance to be reduced) before the node itself. /// The algorithm’s behavior when visiting node _n_ /// depends on hether the region at _n_ /// is acyclic (has no loop) or not. For an acyclic region, the /// algorithm tries to match the subgraph /// at _n_to an acyclic schemas (3.2). If there is no match, /// and the region is a switch candidate, then it attempts to /// refine the region at _n_ into a switch region. /// /// If _n_ is cyclic, the algorithm /// compares the region at _n_ to the cyclic schemata. /// If this fails, it refines _n_ into a loop (3.6). /// /// If both matching and refinement do not make progress, the /// current node _n_ is then skipped for the current iteration of /// the algorithm. If there is an iteration in which all /// nodes are skipped, i.e., the algorithm makes no progress, then /// the algorithm employs a last resort refinement (3.7) to /// ensure that progress can be made in the next iteration. /// </remarks> public Region Execute() { if (proc.Name.EndsWith("2150")) //$DEBUG proc.Name.ToString(); var result = BuildRegionGraph(proc); this.regionGraph = result.Item1; this.entry = result.Item2; int oldCount; int newCount; do { //if (proc.Name.EndsWith()) oldCount = regionGraph.Nodes.Count; this.doms = new DominatorGraph<Region>(this.regionGraph, result.Item2); this.unresolvedCycles = new Queue<Tuple<Region, ISet<Region>>>(); this.unresolvedNoncycles = new Queue<Tuple<Region, ISet<Region>>>(); var postOrder = new DfsIterator<Region>(regionGraph).PostOrder(entry).ToList(); bool didReduce = false; foreach (var n in postOrder) { didReduce = false; do { didReduce = ReduceAcyclic(n, false); if (!didReduce && IsCyclic(n)) { didReduce = ReduceCyclic(n); } } while (didReduce); } newCount = regionGraph.Nodes.Count; if (newCount == oldCount && newCount > 1) { // Didn't make any progress this round, // try refining unstructured regions ProcessUnresolvedRegions(); } } while (regionGraph.Nodes.Count > 1); return entry; }
/// <summary> /// </summary> /// <remarks> /// The algorithm visits nodes in post-order in each iteration. This /// means that all descendants of a node will be visited (and /// hence had the chance to be reduced) before the node itself. /// The algorithm’s behavior when visiting node _n_ /// depends on hether the region at _n_ /// is acyclic (has no loop) or not. For an acyclic region, the /// algorithm tries to match the subgraph /// at _n_to an acyclic schemas (3.2). If there is no match, /// and the region is a switch candidate, then it attempts to /// refine the region at _n_ into a switch region. /// /// If _n_ is cyclic, the algorithm /// compares the region at _n_ to the cyclic schemata. /// If this fails, it refines _n_ into a loop (3.6). /// /// If both matching and refinement do not make progress, the /// current node _n_ is then skipped for the current iteration of /// the algorithm. If there is an iteration in which all /// nodes are skipped, i.e., the algorithm makes no progress, then /// the algorithm employs a last resort refinement (3.7) to /// ensure that progress can be made in the next iteration. /// </remarks> public Region Execute() { var result = BuildRegionGraph(proc); this.regionGraph = result.Item1; var entry = result.Item2; int oldCount; int newCount; DumpGraph(); do { oldCount = regionGraph.Nodes.Count; this.doms = new DominatorGraph<Region>(this.regionGraph, result.Item2); this.postDoms = BuildPostDoms(); this.unresolvedCycles = new Queue<Tuple<Region, ISet<Region>>>(); this.unresolvedNoncycles = new Queue<Tuple<Region, ISet<Region>>>(); this.tailRegions = new Queue<Region>(); var postOrder = new DfsIterator<Region>(regionGraph).PostOrder(entry).ToList(); Debug.Print("== Graph contains {0} nodes ===================================", regionGraph.Nodes.Count); DumpGraph(); bool didReduce = false; foreach (var n in postOrder) { didReduce = false; do { didReduce = ReduceAcyclic(n, false); if (!didReduce && IsCyclic(n)) { didReduce = ReduceCyclic(n); } } while (didReduce); } newCount = regionGraph.Nodes.Count; if (newCount == oldCount) { #if NYI didReduce = false; // Didn't make any progress, try removing tail blocks. foreach (var n in postOrder.Where(n => regionGraph.Nodes.Contains(n))) { didreduce = !IsCyclic(n) && ReduceAcyclic(n, true); if (didreduce) break; } #endif // Didn't make any progress, try to trim away stray gotos. // if (!didReduce) ProcessUnresolvedRegions(); } } while (regionGraph.Nodes.Count > 1); return entry; }