Esempio n. 1
0
        public static void ComputeDominators(LBlock[] blocks)
        {
            BitArray[] doms = new BitArray[blocks.Length];
            for (int i = 0; i < doms.Length; i++)
            {
                doms[i] = new BitArray(doms.Length);
            }

            doms[0].Set(0, true);

            for (int i = 1; i < blocks.Length; i++)
            {
                for (int j = 0; j < blocks.Length; j++)
                {
                    doms[i].SetAll(true);
                }
            }

            // Compute dominators.
            bool changed;

            do
            {
                changed = false;
                for (int i = 1; i < blocks.Length; i++)
                {
                    LBlock block = blocks[i];
                    for (int j = 0; j < block.numPredecessors; j++)
                    {
                        LBlock   pred = block.getPredecessor(j);
                        BitArray u    = new BitArray(doms[i]);
                        doms[block.id].And(doms[pred.id]);
                        doms[block.id].Set(block.id, true);
                        if (!CompareBitArrays(doms[block.id], u))
                        {
                            changed = true;
                        }
                    }
                }
            }while (changed);

            // Turn the bit vectors into lists.
            for (int i = 0; i < blocks.Length; i++)
            {
                LBlock        block = blocks[i];
                List <LBlock> list  = new List <LBlock>();
                for (int j = 0; j < blocks.Length; j++)
                {
                    if (doms[block.id][j])
                    {
                        list.Add(blocks[j]);
                    }
                }
                block.setDominators(list.ToArray());
            }
        }
Esempio n. 2
0
            public void scan(LBlock block)
            {
                for (var i = 0; i < block.numPredecessors; i++)
                {
                    var pred = block.getPredecessor(i);

                    // Has this block already been scanned?
                    if (pred.loop == backedge_.loop)
                    {
                        continue;
                    }

                    pred = SkipContainedLoop(pred, backedge_.loop);

                    // If this assert hits, there is probably a |break| keyword.
                    //Debug.Assert(pred.loop == null || pred.loop == backedge_.loop);
                    if (pred.loop != null)
                    {
                        continue;
                    }

                    stack_.Push(pred);
                }
            }
Esempio n. 3
0
        private ControlType findLoopJoinAndBody(NodeBlock header, NodeBlock effectiveHeader,
                                                out NodeBlock join, out NodeBlock body, out NodeBlock cond)
        {
            //Debug.Assert(effectiveHeader.lir.numSuccessors == 2);

            LBlock succ1 = effectiveHeader.lir.getSuccessor(0);
            LBlock succ2 = effectiveHeader.lir.getSuccessor(1);

            if (succ1.loop != header.lir || succ2.loop != header.lir)
            {
                //Debug.Assert(succ1.loop == header.lir || succ2.loop == header.lir);
                if (succ1.loop != header.lir)
                {
                    join = graph_[succ1.id];
                    body = graph_[succ2.id];
                }
                else
                {
                    join = graph_[succ2.id];
                    body = graph_[succ1.id];
                }
                cond = header;

                // If this is a self-loop, it is more correct to decompose it
                // to a do-while loop. This may not be source accurate in the
                // case of something like |while (x);| but it catches many more
                // source-accurate cases.
                if (header == effectiveHeader &&
                    BlockAnalysis.GetEmptyTarget(body) == header)
                {
                    body = null;
                    return(ControlType.DoWhileLoop);
                }

                return(ControlType.WhileLoop);
            }
            else
            {
                // Neither successor of the header exits the loop, so this is
                // probably a do-while loop. For now, assume it's simple.
                //Debug.Assert(header == effectiveHeader);
                LBlock backedge = header.lir.backedge;
                if (BlockAnalysis.GetEmptyTarget(graph_[backedge.id]) == header)
                {
                    // Skip an empty block sitting in between the backedge and
                    // the condition.
                    //Debug.Assert(backedge.numPredecessors == 1);
                    backedge = backedge.getPredecessor(0);
                }

                //Debug.Assert(backedge.numSuccessors == 2);
                succ1 = backedge.getSuccessor(0);
                succ2 = backedge.getSuccessor(1);

                body = header;
                cond = graph_[backedge.id];
                if (succ1.loop != header.lir)
                {
                    join = graph_[succ1.id];
                }
                else
                {
                    //Debug.Assert(succ2.loop != header.lir);
                    join = graph_[succ2.id];
                }
                return(ControlType.DoWhileLoop);
            }
        }
Esempio n. 4
0
            public void scan(LBlock block)
            {
                for (int i = 0; i < block.numPredecessors; i++)
                {
                    LBlock pred = block.getPredecessor(i);

                    // Has this block already been scanned?
                    if (pred.loop == backedge_.loop)
                        continue;

                    pred = SkipContainedLoop(pred, backedge_.loop);

                    // If this assert hits, there is probably a |break| keyword.
                    //Debug.Assert(pred.loop == null || pred.loop == backedge_.loop);
                    if (pred.loop != null)
                        continue;

                    stack_.Push(pred);
                }
            }
Esempio n. 5
0
        // From Engineering a Compiler (Cooper, Torczon)
        public static bool IsReducible(LBlock[] blocks)
        {
            // Copy the graph into a temporary mutable structure.
            RBlock[] rblocks = new RBlock[blocks.Length];
            for (int i = 0; i < blocks.Length; i++)
            {
                rblocks[i] = new RBlock(i);
            }

            for (int i = 0; i < blocks.Length; i++)
            {
                LBlock block  = blocks[i];
                RBlock rblock = rblocks[i];
                for (int j = 0; j < block.numPredecessors; j++)
                {
                    rblock.predecessors.Add(rblocks[block.getPredecessor(j).id]);
                }
                for (int j = 0; j < block.numSuccessors; j++)
                {
                    rblock.successors.Add(rblocks[block.getSuccessor(j).id]);
                }
            }

            // Okay, start reducing.
            LinkedList <RBlock> queue = new LinkedList <RBlock>(rblocks);

            for (;;)
            {
                List <RBlock> deleteQueue = new List <RBlock>();
                foreach (RBlock rblock in queue)
                {
                    // Transformation T1, remove self-edges.
                    if (rblock.predecessors.Contains(rblock))
                    {
                        rblock.predecessors.Remove(rblock);
                    }
                    if (rblock.successors.Contains(rblock))
                    {
                        rblock.successors.Remove(rblock);
                    }

                    // Transformation T2, remove blocks with one predecessor,
                    // reroute successors' predecessors.
                    if (rblock.predecessors.Count == 1)
                    {
                        // Mark this node for removal since C# sucks and can't delete during iteration.
                        deleteQueue.Add(rblock);

                        RBlock predecessor = rblock.predecessors[0];

                        // Delete the edge from pred -> me
                        predecessor.successors.Remove(rblock);

                        for (int i = 0; i < rblock.successors.Count; i++)
                        {
                            RBlock successor = rblock.successors[i];
                            //Debug.Assert(successor.predecessors.Contains(rblock));
                            successor.predecessors.Remove(rblock);
                            if (!successor.predecessors.Contains(predecessor))
                            {
                                successor.predecessors.Add(predecessor);
                            }

                            if (!predecessor.successors.Contains(successor))
                            {
                                predecessor.successors.Add(successor);
                            }
                        }
                    }
                }

                if (deleteQueue.Count == 0)
                {
                    break;
                }

                foreach (RBlock rblock in deleteQueue)
                {
                    queue.Remove(rblock);
                }
            }

            // If the graph reduced to one node, it was reducible.
            return(queue.Count == 1);
        }