Beispiel #1
0
    /*
     * Test Building Full Dominator Tree
     */
    private static void TestCalculatingDominanceFrontier(int index, SortedSet <int> expected)
    {
        // Build Dominator Tree
        IRGraph       cfg           = BuildSampleCFG();
        DominatorTree dominatorTree = new DominatorTree(cfg);

        SortedSet <IRBlock> result    = dominatorTree.GetDominanceFrontier(cfg.GetBlock(index));
        SortedSet <int>     intResult = ConvertToIndexSet(result);

        if (!intResult.SetEquals(expected))
        {
            throw new Exception("Dominance frontier for block " + index + " is " + ConvertSetToString(intResult) + " should be " + ConvertSetToString(expected));
        }
    }
        private LoopType DetermineLoopType(HashSet <ILogicalConstruct> loopBody, HashSet <ILogicalConstruct> latchingNodes, IntervalConstruct interval, DominatorTree dominatorTree, out ConditionLogicalConstruct loopCondition)
        {
            V_0       = interval.get_Entry() as ILogicalConstruct;
            V_1       = new HashSet <ILogicalConstruct>(latchingNodes);
            dummyVar0 = V_1.Add(V_0);
            V_2       = DFSTBuilder.BuildTree(V_0.get_Parent() as ILogicalConstruct);
            V_3       = new HashSet <ILogicalConstruct>();
            V_4       = loopBody.GetEnumerator();
            try
            {
                while (V_4.MoveNext())
                {
                    V_5 = V_4.get_Current();
                    V_6 = dominatorTree.GetDominanceFrontier(V_5).GetEnumerator();
                    try
                    {
                        while (V_6.MoveNext())
                        {
                            V_7 = (ILogicalConstruct)V_6.get_Current();
                            if (!interval.get_Children().Contains(V_7) || loopBody.Contains(V_7))
                            {
                                continue;
                            }
                            dummyVar1 = V_3.Add(V_7);
                        }
                    }
                    finally
                    {
                        ((IDisposable)V_6).Dispose();
                    }
                }
            }
            finally
            {
                ((IDisposable)V_4).Dispose();
            }
            if (V_3.get_Count() == 0)
            {
                V_8 = V_2.get_ReversePostOrder().GetEnumerator();
                try
                {
                    while (V_8.MoveNext())
                    {
                        V_9 = V_8.get_Current().get_Construct() as ILogicalConstruct;
                        if (loopBody.Contains(V_9))
                        {
                            continue;
                        }
                        loopCondition = this.GetLoopConditionWithMaxIndex(V_2, loopBody, V_1, V_9);
                        if (loopCondition == null)
                        {
                            continue;
                        }
                        this.ExpandLoopBody(interval, loopBody, V_9);
                        if (loopCondition != V_0)
                        {
                            V_10 = 2;
                            goto Label1;
                        }
                        else
                        {
                            V_10 = 1;
                            goto Label1;
                        }
                    }
                    goto Label0;
                }
                finally
                {
                    ((IDisposable)V_8).Dispose();
                }
Label1:
                return(V_10);
            }
            V_11 = V_2.get_ReversePostOrder().get_Count();
            V_4  = V_3.GetEnumerator();
            try
            {
                while (V_4.MoveNext())
                {
                    V_13 = V_4.get_Current();
                    V_14 = V_2.get_ConstructToNodeMap().get_Item(V_13).get_ReversePostOrderIndex();
                    if (V_14 >= V_11)
                    {
                        continue;
                    }
                    V_11 = V_14;
                }
            }
            finally
            {
                ((IDisposable)V_4).Dispose();
            }
            V_12          = V_2.get_ReversePostOrder().get_Item(V_11).get_Construct() as ILogicalConstruct;
            loopCondition = this.GetLoopConditionWithMaxIndex(V_2, loopBody, V_1, V_12);
            this.ExpandLoopBody(interval, loopBody, V_12);
            if (loopCondition == null)
            {
                return(0);
            }
            if (loopCondition == V_0)
            {
                return(1);
            }
            return(2);

Label0:
            if (!this.CanBeLoopCondition(V_0, loopBody))
            {
                loopCondition = null;
                return(0);
            }
            loopCondition = V_0 as ConditionLogicalConstruct;
            return(1);
        }
Beispiel #3
0
    private static void InsertPhiFunctions(IRGraph graph, DominatorTree dominatorTree)
    {
        foreach (IRBlock block in graph.GetSetOfAllBlocks())
        {
            Console.WriteLine();
            Console.WriteLine("***");
            Console.WriteLine("Block: " + block.GetIndex());
            block.PrintStatements();

            Console.Write("Predecessors: ");
            foreach (IRBlock pred in graph.GetPredecessors(block))
            {
                Console.Write(pred.GetIndex() + ", ");
            }
            Console.WriteLine();

            Console.Write("Live in : ");
            foreach (Ident ident in block.GetLiveIn())
            {
                Console.Write(ident + ", ");
            }
            Console.WriteLine();

            Console.Write("Defined vars: ");
            foreach (Ident ident in block.GetDefinedVars())
            {
                Console.Write(ident + ", ");
            }
            Console.WriteLine();
        }

        foreach (Ident v in graph.GetDefinedVars())
        {
            // A(v) = blocks containing an assignment to v
            HashSet <IRBlock> Av = new HashSet <IRBlock>();
            foreach (IRBlock block in graph.GetSetOfAllBlocks())
            {
                if (block.GetDefinedVars().Contains(v) && block.GetLiveIn().Contains(v))
                {
                    Av.Add(block);
                }
            }

            // place Phi tuple for each v in the iterated dominance frontier of A(v)
            HashSet <IRBlock> needsPhiFunction = new HashSet <IRBlock>();
            foreach (IRBlock Avblock in Av)
            {
                // create set of blocks that need phi functions
                foreach (IRBlock block in dominatorTree.GetDominanceFrontier(Avblock))
                {
                    needsPhiFunction.Add(block);
                }
            }

            // only want one phi function per block for each variable where appropiate
            foreach (IRBlock block in needsPhiFunction)
            {
                // Phi function should have as many arguments as it does predecessors
                List <Ident> sources = new List <Ident>();
                foreach (IRBlock b in graph.GetPredecessors(block))
                {
                    sources.Add(v);
                }

                IRTupleManyOp phi = new IRTupleManyOp(IrOp.PHI, v, sources);

                block.InsertStatement(phi, 0);
                Console.WriteLine("** SSA: Inserting phi function: " + phi.toString() + " into block " + block.GetIndex());
            }
        }
    }
        /// <summary>
        /// Determines the type of the loop and the condition of the loop. Adds additional nodes into the loop body.
        /// </summary>
        /// <param name="loopBody"></param>
        /// <param name="header"></param>
        /// <param name="latchingNodes"></param>
        /// <param name="interval"></param>
        /// <param name="loopCondition"></param>
        /// <returns></returns>
        private LoopType DetermineLoopType(HashSet <ILogicalConstruct> loopBody, HashSet <ILogicalConstruct> latchingNodes,
                                           IntervalConstruct interval, DominatorTree dominatorTree, out ConditionLogicalConstruct loopCondition)
        {
            ILogicalConstruct           header     = interval.Entry as ILogicalConstruct;
            HashSet <ILogicalConstruct> legalExits = new HashSet <ILogicalConstruct>(latchingNodes);

            legalExits.Add(header);

            ILogicalConstruct parentConstruct = header.Parent as ILogicalConstruct;
            DFSTree           dfsTree         = DFSTBuilder.BuildTree(parentConstruct);

            //B - nodes in the loop body (= loopBody)
            //I - nodes in the interval (= interval.Children)
            //U - union of all of the dominance frontiers of the nodes in B
            //exitDominanceFrontier = (U n I) \ B
            //If a node is in the exitDominanceFrontier, then it is dominated by the header and is a successor (not necessarily direct) of more than one
            //node in the loop body.
            HashSet <ILogicalConstruct> exitDominanceFrontier = new HashSet <ILogicalConstruct>();

            foreach (ILogicalConstruct loopNode in loopBody)
            {
                foreach (ILogicalConstruct frontierNode in dominatorTree.GetDominanceFrontier(loopNode))
                {
                    if (interval.Children.Contains(frontierNode) && !loopBody.Contains(frontierNode))
                    {
                        exitDominanceFrontier.Add(frontierNode);
                    }
                }
            }

            //This is leftover heuristic, that was used for determining a suitable successor that is going to be follow node of the loop.
            //Changing it now will break a good number of the tests. Since the produced output is acceptable, until a better heuristic is found
            //there is no need to change it.
            if (exitDominanceFrontier.Count == 0)
            {
                //If the exit dominance frontier is empty then we look for the node, with minimum post order index, that is a successor of a condition loop exit.
                //The desired exit should be a condition in order to reduce the number of infinite loops (heuristic).
                foreach (DFSTNode dfsNode in dfsTree.ReversePostOrder)
                {
                    ILogicalConstruct construct = dfsNode.Construct as ILogicalConstruct;
                    if (loopBody.Contains(construct))
                    {
                        continue;
                    }

                    loopCondition = GetLoopConditionWithMaxIndex(dfsTree, loopBody, legalExits, construct);
                    //By taking the successor with the minimum post order index and the loop exit with the maximum post order index, we ensure that
                    //the produced construct will always be the same, since the post order in our case is a total order.
                    //There are other various ways of finding the exit-successor pair that can bring consistent output, but none of them is found to yield
                    //better results than the rest.
                    if (loopCondition != null)
                    {
                        //We expand the loop body only when we've found a condition successor of the loop.
                        //This is done in order to avoid adding all of the dominated nodes of an infinite loop to the body. (Better readability of the final code.)
                        //E.g.: An infinite loop on the top level of the logical tree (i.e. child of the method block construct). If it dominates all of its
                        //succeeding nodes then they will be in its interval, which means that they will be added to the loop. As a result there will
                        //be an infinite loop at the end of the method, that encloses a cood part of the code, for no apparent reason.
                        ExpandLoopBody(interval, loopBody, construct);

                        if (loopCondition == header)
                        {
                            return(LoopType.PreTestedLoop);
                        }
                        else
                        {
                            return(LoopType.PostTestedLoop);
                        }
                    }
                }

                if (CanBeLoopCondition(header, loopBody))
                {
                    loopCondition = header as ConditionLogicalConstruct;
                    return(LoopType.PreTestedLoop);
                }
                else
                {
                    loopCondition = null;
                    return(LoopType.InfiniteLoop);
                }
            }
            else
            {
                //If there are nodes in the exitDominanceFrontier, then we choose the one with the minimum postorder index for successor of the loop.
                //Then we try to find a condition exit of the loop, with maximum post order index, that is predecessor of the successor node.
                int minOrderIndexOfSuccessor = dfsTree.ReversePostOrder.Count;
                foreach (ILogicalConstruct successor in exitDominanceFrontier)
                {
                    int currentOrderIndex = dfsTree.ConstructToNodeMap[successor].ReversePostOrderIndex;

                    if (currentOrderIndex < minOrderIndexOfSuccessor)
                    {
                        minOrderIndexOfSuccessor = currentOrderIndex;
                    }
                }

                ILogicalConstruct loopSuccessor = dfsTree.ReversePostOrder[minOrderIndexOfSuccessor].Construct as ILogicalConstruct;

                loopCondition = GetLoopConditionWithMaxIndex(dfsTree, loopBody, legalExits, loopSuccessor);

                ExpandLoopBody(interval, loopBody, loopSuccessor);

                if (loopCondition != null)
                {
                    if (loopCondition == header)
                    {
                        return(LoopType.PreTestedLoop);
                    }
                    else
                    {
                        return(LoopType.PostTestedLoop);
                    }
                }
                else
                {
                    return(LoopType.InfiniteLoop);
                }
            }
        }
Beispiel #5
0
    private static void InsertPhiFunctions(IRGraph graph, DominatorTree dominatorTree)
    {
        foreach (IRBlock block in graph.GetSetOfAllBlocks())
        {
          Console.WriteLine();
          Console.WriteLine("***");
          Console.WriteLine("Block: " + block.GetIndex());
          block.PrintStatements();

          Console.Write("Predecessors: ");
          foreach (IRBlock pred in graph.GetPredecessors(block))
        Console.Write(pred.GetIndex() + ", ");
          Console.WriteLine();

          Console.Write("Live in : ");
          foreach (Ident ident in block.GetLiveIn())
        Console.Write(ident + ", ");
          Console.WriteLine();

          Console.Write("Defined vars: ");
          foreach (Ident ident in block.GetDefinedVars())
        Console.Write(ident + ", ");
          Console.WriteLine();
        }

        foreach (Ident v in graph.GetDefinedVars())
        {
          // A(v) = blocks containing an assignment to v
          HashSet<IRBlock> Av = new HashSet<IRBlock>();
          foreach (IRBlock block in graph.GetSetOfAllBlocks())
          {
        if (block.GetDefinedVars().Contains(v) && block.GetLiveIn().Contains(v))
          Av.Add(block);
          }

          // place Phi tuple for each v in the iterated dominance frontier of A(v)
          HashSet<IRBlock> needsPhiFunction = new HashSet<IRBlock>();
          foreach (IRBlock Avblock in Av)
          {
        // create set of blocks that need phi functions
        foreach (IRBlock block in dominatorTree.GetDominanceFrontier(Avblock))
        {
          needsPhiFunction.Add(block);
        }
          }

          // only want one phi function per block for each variable where appropiate
          foreach (IRBlock block in needsPhiFunction)
          {
        // Phi function should have as many arguments as it does predecessors
        List<Ident> sources = new List<Ident>();
        foreach (IRBlock b in graph.GetPredecessors(block))
          sources.Add(v);

        IRTupleManyOp phi = new IRTupleManyOp(IrOp.PHI, v, sources);

        block.InsertStatement(phi, 0);
        Console.WriteLine("** SSA: Inserting phi function: " + phi.toString() + " into block " + block.GetIndex());
          }
        }
    }
Beispiel #6
0
 private bool TryBuildIfConstruct(ConditionLogicalConstruct condition, DominatorTree dominatorTree, DFSTree dfsTree)
 {
     V_0             = condition.get_FalseSuccessor();
     V_1             = condition.get_TrueSuccessor();
     V_2             = dominatorTree.GetDominanceFrontier(V_0);
     V_3             = dominatorTree.GetDominanceFrontier(V_1);
     stackVariable15 = this.CheckSuccessor(condition, V_1, V_2, dfsTree);
     if (stackVariable15 == null)
     {
         dummyVar0       = stackVariable15;
         stackVariable15 = this.CheckSuccessor(condition, V_0, V_3, dfsTree);
     }
     V_4 = new HashSet <ISingleEntrySubGraph>(V_3);
     V_4.IntersectWith(V_2);
     if (stackVariable15 == null && V_2.get_Count() > 0 && V_3.get_Count() > 0 && V_4.get_Count() == 0)
     {
         return(false);
     }
     V_5 = this.GetBlockBody(dominatorTree, V_1, condition);
     V_6 = this.GetBlockBody(dominatorTree, V_0, condition);
     if (V_5 == null && V_6 == null)
     {
         return(false);
     }
     if (V_5 == null)
     {
         condition.Negate(this.typeSystem);
         stackVariable86 = V_1;
         V_1             = V_0;
         V_0             = stackVariable86;
         V_5             = V_6;
         V_6             = null;
     }
     if (V_6 == null && !this.CheckSuccessors(V_5, V_0))
     {
         return(false);
     }
     if (this.ShouldInvertIfAndRemoveElse(V_5, V_1, V_6, V_0))
     {
         condition.Negate(this.typeSystem);
         stackVariable73 = V_1;
         V_1             = V_0;
         V_0             = stackVariable73;
         stackVariable75 = V_5;
         V_5             = V_6;
         V_6             = stackVariable75;
         V_6             = null;
     }
     if (V_6 != null && !this.HasSuccessors(V_5))
     {
         stackVariable61    = V_1.get_FirstBlock().get_TheBlock();
         stackVariable63    = new Code[2];
         stackVariable63[0] = 41;
         stackVariable63[1] = 119;
         if (this.SubtreeEndsInInstructionCode(stackVariable61, stackVariable63))
         {
             V_6 = null;
         }
     }
     V_7 = new BlockLogicalConstruct(V_1, V_5);
     if (V_6 != null)
     {
         stackVariable46 = new BlockLogicalConstruct(V_0, V_6);
     }
     else
     {
         stackVariable46 = null;
     }
     this.UpdateDominatorTree(dominatorTree, IfLogicalConstruct.GroupInIfConstruct(condition, V_7, stackVariable46));
     return(true);
 }
    /*
       * Test Building Full Dominator Tree
       */
    private static void TestCalculatingDominanceFrontier(int index, SortedSet<int> expected)
    {
        // Build Dominator Tree
        IRGraph cfg = BuildSampleCFG();
        DominatorTree dominatorTree = new DominatorTree(cfg);

        SortedSet<IRBlock> result = dominatorTree.GetDominanceFrontier(cfg.GetBlock(index));
        SortedSet<int> intResult = ConvertToIndexSet(result);

        if(!intResult.SetEquals(expected)) {
          throw new Exception("Dominance frontier for block " + index + " is " + ConvertSetToString(intResult) + " should be " + ConvertSetToString(expected));
        }
    }
Beispiel #8
0
        /// <summary>
        /// Tries to build an if construct with condition - the specified condition.
        /// </summary>
        /// <remarks>
        /// The idea is to get the dominated nodes of the true successor to create the then block and the dominated nodes of the false successor
        /// to create the else block.
        /// If both the then and else blocks have successors, then they must have a common successor to create the if construct.
        /// </remarks>
        /// <param name="condition"></param>
        /// <returns>True on success.</returns>
        private bool TryBuildIfConstruct(ConditionLogicalConstruct condition, DominatorTree dominatorTree, DFSTree dfsTree)
        {
            //Store the true and false successors for optimization.
            ILogicalConstruct falseSuccessor = condition.FalseSuccessor;
            ILogicalConstruct trueSuccessor  = condition.TrueSuccessor;

            HashSet <ISingleEntrySubGraph> falseSuccessorFrontier = dominatorTree.GetDominanceFrontier(falseSuccessor);
            HashSet <ISingleEntrySubGraph> trueSuccessorFrontier  = dominatorTree.GetDominanceFrontier(trueSuccessor);

            ILogicalConstruct exitSuccessor = CheckSuccessor(condition, trueSuccessor, falseSuccessorFrontier, dfsTree) ??
                                              CheckSuccessor(condition, falseSuccessor, trueSuccessorFrontier, dfsTree);

            HashSet <ISingleEntrySubGraph> frontierIntersection = new HashSet <ISingleEntrySubGraph>(trueSuccessorFrontier);

            frontierIntersection.IntersectWith(falseSuccessorFrontier);

            if (exitSuccessor == null && falseSuccessorFrontier.Count > 0 && trueSuccessorFrontier.Count > 0 && frontierIntersection.Count == 0)
            {
                //If none of the successors can be a proper exit and the false and true successor frontiers are not empty but have no common node,
                //then we do not make the if since it will not have a common exit.
                return(false);
            }

            HashSet <ILogicalConstruct> thenBody = GetBlockBody(dominatorTree, trueSuccessor, condition);
            HashSet <ILogicalConstruct> elseBody = GetBlockBody(dominatorTree, falseSuccessor, condition);

            if (thenBody == null && elseBody == null)
            {
                return(false);
            }
            else if (thenBody == null)
            {
                condition.Negate(typeSystem);

                ILogicalConstruct swapHelper = trueSuccessor;
                trueSuccessor  = falseSuccessor;
                falseSuccessor = swapHelper;

                thenBody = elseBody;
                elseBody = null;
            }

            //If the else body is null but the false successor is not a successor of the then body then we do not make the if.
            if (elseBody == null && !CheckSuccessors(thenBody, falseSuccessor))
            {
                return(false);
            }

            if (ShouldInvertIfAndRemoveElse(thenBody, trueSuccessor, elseBody, falseSuccessor))
            {
                ///This is performed for cosmetic reasons.
                condition.Negate(typeSystem);

                ILogicalConstruct successorSwapHelper = trueSuccessor;
                trueSuccessor  = falseSuccessor;
                falseSuccessor = successorSwapHelper;

                HashSet <ILogicalConstruct> swapHelper = thenBody;
                thenBody = elseBody;
                elseBody = swapHelper;
                elseBody = null;
            }
            if (elseBody != null && !HasSuccessors(thenBody) &&
                SubtreeEndsInInstructionCode(trueSuccessor.FirstBlock.TheBlock, new Code[] { Code.Ret, Code.Throw }))             // check if all ends are throw and/or return -> allow mixed ends as well
            {
                // we don't need the else
                elseBody = null;
            }

            BlockLogicalConstruct theThenBlock = new BlockLogicalConstruct(trueSuccessor, thenBody);
            BlockLogicalConstruct theElseBlock = elseBody != null ? new BlockLogicalConstruct(falseSuccessor, elseBody) : null;

            IfLogicalConstruct theIfConstruct = IfLogicalConstruct.GroupInIfConstruct(condition, theThenBlock, theElseBlock);

            UpdateDominatorTree(dominatorTree, theIfConstruct);
            return(true);
        }