Esempio n. 1
0
 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);
         }
     }
 }
Esempio n. 2
0
        /// <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;
        }
Esempio n. 3
0
        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;
        }
Esempio n. 4
0
        /// <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);
        }
Esempio n. 5
0
        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);
            }
        }
Esempio n. 6
0
        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);
                }
            }
        }
Esempio n. 7
0
 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;
 }
Esempio n. 8
0
        /// <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;
        }
Esempio n. 9
0
        /// <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;
        }