private void GenerateTryFinallyHandler(YieldExceptionHandlerInfo handlerInfo)
 {
     this.finallyBlocks = new HashSet <ILogicalConstruct>();
     this.entryOfTry    = this.GetStateBeginBlockConstruct(handlerInfo.get_TryStates());
     this.BuildTryBody(handlerInfo);
     if (handlerInfo.get_HandlerType() != YieldExceptionHandlerType.Method)
     {
         V_0 = this.GenerateFinallyBlock();
     }
     else
     {
         if (this.newFinallyBody == null)
         {
             throw new Exception("Could not determine the end ot the try block");
         }
         this.RemoveExcessNodesFromTheTryBlock();
         this.ProcessFinallyNodes();
         stackVariable31    = this.newFinallyBody;
         stackVariable33    = new ILogicalConstruct[1];
         stackVariable33[0] = this.newFinallyBody;
         V_0 = new BlockLogicalConstruct(stackVariable31, stackVariable33);
     }
     V_1 = new TryFinallyLogicalConstruct(new BlockLogicalConstruct(this.entryOfTry, this.newTryBody), V_0);
     this.createdConstructsToIntervalMap.set_Item(V_1, handlerInfo);
     this.CleanUpOrderedNodes(V_1);
     return;
 }
예제 #2
0
 private bool CanBeLoopCondition(ILogicalConstruct node, HashSet <ILogicalConstruct> loopBody)
 {
     if (!loopBody.Contains(node))
     {
         return(false);
     }
     if (node as ConditionLogicalConstruct == null)
     {
         return(false);
     }
     V_0 = 0;
     V_1 = node.get_SameParentSuccessors().GetEnumerator();
     try
     {
         while (V_1.MoveNext())
         {
             V_2 = (ILogicalConstruct)V_1.get_Current();
             if (!loopBody.Contains(V_2))
             {
                 continue;
             }
             V_0 = V_0 + 1;
         }
     }
     finally
     {
         ((IDisposable)V_1).Dispose();
     }
     return(V_0 == 1);
 }
예제 #3
0
        private void ProcessGotoFlowConstructs(BlockLogicalConstruct theConstruct)
        {
            ILogicalConstruct[] sortedChildren = new ILogicalConstruct[theConstruct.Children.Count];
            int index = 0;

            foreach (ILogicalConstruct child in theConstruct.Children)
            {
                sortedChildren[index++] = child;
            }
            Array.Sort <ISingleEntrySubGraph>(sortedChildren);

            HashSet <ILogicalConstruct> usedAsFollow = new HashSet <ILogicalConstruct>();

            foreach (ILogicalConstruct currentChild in sortedChildren)
            {
                if (visitedConstructs.Add(currentChild))
                {
                    if (visitedConstructs.Contains(currentChild.FollowNode) || !usedAsFollow.Add(currentChild.FollowNode))
                    {
                        currentChild.CFGFollowNode = null;
                    }

                    ProcessLogicalConstruct(currentChild);
                }
            }
        }
        /// <summary>
        /// Removes the inner nodes of the try that are reachable by the finally node.
        /// </summary>
        /// <remarks>
        /// Do not traverse the entry of the try since there can be an actual loop.
        /// </remarks>
        private void RemoveExcessNodesFromTheTryBlock()
        {
            HashSet <ILogicalConstruct> markedForTraversal = new HashSet <ILogicalConstruct>(finallyBlocks);
            Queue <ILogicalConstruct>   bfsQueue           = new Queue <ILogicalConstruct>(finallyBlocks);

            while (bfsQueue.Count > 0)
            {
                ILogicalConstruct current = bfsQueue.Dequeue();
                foreach (ILogicalConstruct successor in current.SameParentSuccessors)
                {
                    if (!markedForTraversal.Contains(successor) && successor != entryOfTry)
                    {
                        markedForTraversal.Add(successor);
                        bfsQueue.Enqueue(successor);
                    }
                }
            }

            foreach (ILogicalConstruct node in markedForTraversal)
            {
                if (node != entryOfTry)
                {
                    newTryBody.Remove(node);
                }
            }
        }
 private void DetermineLoopBodyBlock(ILogicalConstruct entry, HashSet <ILogicalConstruct> loopBodyNodes)
 {
     this.set_LoopBodyBlock(null);
     if (loopBodyNodes.get_Count() > 0)
     {
         if (this.get_LoopType() != 1)
         {
             if (!loopBodyNodes.Contains(entry))
             {
                 throw new Exception("Invalid entry of loop body.");
             }
             this.set_LoopBodyBlock(new BlockLogicalConstruct(entry, loopBodyNodes));
             return;
         }
         V_0 = this.get_LoopCondition().get_TrueSuccessor();
         if (V_0 == null || !loopBodyNodes.Contains(V_0))
         {
             V_0 = this.get_LoopCondition().get_FalseSuccessor();
         }
         if (V_0 == null || !loopBodyNodes.Contains(V_0))
         {
             throw new Exception("Invalid entry of loop body.");
         }
         this.set_LoopBodyBlock(new BlockLogicalConstruct(V_0, loopBodyNodes));
     }
     return;
 }
        /// <summary>
        /// Builds the try body of the specified exception handler starting from the given entry node.
        /// </summary>
        /// <remarks>
        /// We assume that all nodes before reaching the finally block are in the try construct.
        /// </remarks>
        /// <param name="handlerInfo"></param>
        /// <param name="entryOfTry"></param>
        private void BuildTryBody(YieldExceptionHandlerInfo handlerInfo)
        {
            newTryBody = new HashSet <ILogicalConstruct>();
            newTryBody.Add(entryOfTry);
            newFinallyBody = null;

            HashSet <ILogicalConstruct> traversedNodes = new HashSet <ILogicalConstruct>();
            Queue <ILogicalConstruct>   bfsQueue       = new Queue <ILogicalConstruct>();

            foreach (ILogicalConstruct successor in entryOfTry.SameParentSuccessors)
            {
                bfsQueue.Enqueue(successor);
            }

            while (bfsQueue.Count > 0)
            {
                ILogicalConstruct currentNode = bfsQueue.Dequeue();
                if (!traversedNodes.Add(currentNode) || finallyBlocks.Contains(currentNode))
                {
                    continue;
                }

                ProcessCurrentNode(handlerInfo, bfsQueue, currentNode);
            }
        }
 private void DetermineFollowNodesInSubGraph(ILogicalConstruct theGraph)
 {
     this.GetVerticesAndAdjacencyMatrix(theGraph);
     V_0 = MaxWeightDisjointPathsFinder.GetOptimalEdgesInDAG(this.adjacencyMatrix).GetEnumerator();
     try
     {
         while (V_0.MoveNext())
         {
             V_1 = V_0.get_Current();
             this.orderedVertexArray[V_1.get_Key()].set_CFGFollowNode(this.orderedVertexArray[V_1.get_Value()].get_FirstBlock());
             if (this.orderedVertexArray[V_1.get_Key()] as ConditionLogicalConstruct == null)
             {
                 continue;
             }
             V_2 = this.orderedVertexArray[V_1.get_Key()] as ConditionLogicalConstruct;
             if (V_2.get_CFGFollowNode() != V_2.get_TrueCFGSuccessor())
             {
                 continue;
             }
             V_2.Negate(this.typeSystem);
         }
     }
     finally
     {
         ((IDisposable)V_0).Dispose();
     }
     return;
 }
예제 #8
0
        /// <summary>
        /// Gets a collection of all possible latching nodes for a loop. Builds the body of the loop in the process.
        /// </summary>
        /// <param name="tree">The tree in which the loop was found.</param>
        /// <param name="loopBody">On exit contains the resulted loop body.</param>
        /// <returns>Returns collection of all possible latching nodes.</returns>
        private HashSet <ILogicalConstruct> BuildLoop(DFSTree tree, out HashSet <ILogicalConstruct> loopBody)
        {
            loopBody = new HashSet <ILogicalConstruct>();
            HashSet <ILogicalConstruct> possibleLatchingNodes = new HashSet <ILogicalConstruct>();

            /// Loops are defined by their backedges.
            foreach (DFSTEdge edge in tree.BackEdges)
            {
                ILogicalConstruct header       = edge.End.Construct as ILogicalConstruct;
                ILogicalConstruct latchingNode = edge.Start.Construct as ILogicalConstruct;

                /// The edge between the header and the latching node was marked as goto-edge on an earlier step.
                if (removedEdges.ContainsKey(latchingNode) && removedEdges[latchingNode].Contains(header))
                {
                    continue;
                }

                ICollection <DFSTNode>          shortLoopBody          = tree.GetPath(edge.End, edge.Start);
                ICollection <DFSTNode>          fullLoopBody           = ExpandLoopBodyWithCrossEdges(shortLoopBody);
                ICollection <ILogicalConstruct> fullLoopBodyConstructs = GetConstructsCollection(fullLoopBody);

                if (CanBeLoop(header, latchingNode, fullLoopBody))
                {
                    possibleLatchingNodes.Add(latchingNode);
                    foreach (ILogicalConstruct construct in fullLoopBodyConstructs)
                    {
                        loopBody.Add(construct);
                    }
                }
            }

            return(possibleLatchingNodes);
        }
예제 #9
0
 private void RemoveBackEdgesFromSwitchConstructs(ILogicalConstruct theConstruct)
 {
     V_0 = DFSTBuilder.BuildTree(theConstruct).get_BackEdges().GetEnumerator();
     try
     {
         while (V_0.MoveNext())
         {
             V_1 = V_0.get_Current();
             V_2 = V_1.get_Start().get_Construct() as ILogicalConstruct;
             if (V_2 as ConditionLogicalConstruct != null)
             {
                 continue;
             }
             V_3 = V_2 as CFGBlockLogicalConstruct;
             if (V_3 == null || V_3.get_TheBlock().get_Last().get_OpCode().get_Code() != 68)
             {
                 continue;
             }
             this.MarkAsGotoEdge(V_2, V_1.get_End().get_Construct() as ILogicalConstruct);
         }
     }
     finally
     {
         ((IDisposable)V_0).Dispose();
     }
     return;
 }
예제 #10
0
 private static void AddSuccessorsToCount(ILogicalConstruct construct, Dictionary <CFGBlockLogicalConstruct, uint> numberOfHandlersLeavingToBlock)
 {
     V_0 = construct.get_CFGSuccessors().GetEnumerator();
     try
     {
         while (V_0.MoveNext())
         {
             V_1 = V_0.get_Current();
             if (numberOfHandlersLeavingToBlock.ContainsKey(V_1))
             {
                 stackVariable10 = numberOfHandlersLeavingToBlock;
                 V_2             = V_1;
                 stackVariable10.set_Item(V_2, stackVariable10.get_Item(V_2) + 1);
             }
             else
             {
                 numberOfHandlersLeavingToBlock.Add(V_1, 1);
             }
         }
     }
     finally
     {
         ((IDisposable)V_0).Dispose();
     }
     return;
 }
예제 #11
0
 private void AddNewHeaders(ILogicalConstruct currentHeader, IntervalConstruct currentInterval)
 {
     V_0 = new Stack <ILogicalConstruct>();
     V_1 = new HashSet <ILogicalConstruct>();
     V_0.Push(currentHeader);
     while (V_0.get_Count() > 0)
     {
         V_2 = V_0.Pop();
         if (V_1.Contains(V_2))
         {
             continue;
         }
         dummyVar0 = V_1.Add(V_2);
         V_3       = this.GetNodeSuccessors(V_2).GetEnumerator();
         try
         {
             while (V_3.MoveNext())
             {
                 V_4 = V_3.get_Current();
                 this.CheckAndAddPossibleHeader(V_4, currentInterval, V_0);
             }
         }
         finally
         {
             if (V_3 != null)
             {
                 V_3.Dispose();
             }
         }
     }
     return;
 }
 /// <summary>
 /// Creates a new case logical construct that is not yet attached to the logical tree.
 /// </summary>
 /// <param name="entry"></param>
 public CaseLogicalConstruct(ILogicalConstruct entry)
 {
     this.Entry = entry;
     this.body = new HashSet<ILogicalConstruct>();
     body.Add(entry);
     CaseNumbers = new List<int>();
 }
예제 #13
0
 protected ILogicalConstruct[] GetSortedArrayFromCollection <T>(ICollection <T> collection)
     where T : ISingleEntrySubGraph
 {
     V_0 = new ILogicalConstruct[collection.get_Count()];
     V_1 = 0;
     V_2 = collection.GetEnumerator();
     try
     {
         while (V_2.MoveNext())
         {
             V_3                  = (ILogicalConstruct)(object)V_2.get_Current();
             stackVariable13      = V_1;
             V_1                  = stackVariable13 + 1;
             V_0[stackVariable13] = V_3;
         }
     }
     finally
     {
         if (V_2 != null)
         {
             V_2.Dispose();
         }
     }
     Array.Sort <ISingleEntrySubGraph>(V_0);
     return(V_0);
 }
예제 #14
0
        /// <summary>
        /// Gets the successors (direct or indirect) of the given <paramref name="startNode"/>,
        /// that are in the specified <paramref name="interval"/>.
        /// </summary>
        /// <remarks>
        /// If the start node is not in the interval, then it will not be traversed. This is a corner case for entwined loops.
        /// The start node will not be included in the result, even if it is its own successor.
        /// </remarks>
        /// <returns></returns>
        private HashSet <ILogicalConstruct> GetIntervalSuccessors(IntervalConstruct interval, ILogicalConstruct startNode)
        {
            HashSet <ILogicalConstruct> intervalSuccessors = new HashSet <ILogicalConstruct>();

            if (!interval.Children.Contains(startNode))
            {
                return(intervalSuccessors);
            }

            Queue <ILogicalConstruct> traversalQueue = new Queue <ILogicalConstruct>();

            traversalQueue.Enqueue(startNode);
            HashSet <ILogicalConstruct> traversedNodes = new HashSet <ILogicalConstruct>();

            traversedNodes.Add(startNode);

            while (traversalQueue.Count > 0)
            {
                ILogicalConstruct currentNode = traversalQueue.Dequeue();
                foreach (ILogicalConstruct successor in currentNode.SameParentSuccessors)
                {
                    if (!traversedNodes.Contains(successor) && interval.Children.Contains(successor) && intervalSuccessors.Add(successor))
                    {
                        traversedNodes.Add(successor);
                        traversalQueue.Enqueue(successor);
                    }
                }
            }

            return(intervalSuccessors);
        }
예제 #15
0
        private bool CanBeLoop(ILogicalConstruct header, ILogicalConstruct latchingNode, ICollection <DFSTNode> nodesInLoop)
        {
            if (header == null || latchingNode == null)
            {
                return(false);
            }
            V_0 = this.GetConstructsCollection(nodesInLoop);
            V_1 = V_0.GetEnumerator();
            try
            {
                while (V_1.MoveNext())
                {
                    V_2 = V_1.get_Current();
                    if (this.CanBeInLoop(V_2, V_0, header))
                    {
                        continue;
                    }
                    V_3 = false;
                    goto Label1;
                }
                goto Label0;
            }
            finally
            {
                if (V_1 != null)
                {
                    V_1.Dispose();
                }
            }
Label1:
            return(V_3);

Label0:
            return(true);
        }
예제 #16
0
        /// <summary>
        /// Determines whether the specified <paramref name="node"/> can be a condition to the loop with body - <paramref name="loopBody"/>.
        /// </summary>
        /// <param name="node">The possible condition node.</param>
        /// <param name="loopBody">The body of the loop.</param>
        /// <returns>Returns true, if <paramref name="node"/> can be the condition of the loop.</returns>
        private bool CanBeLoopCondition(ILogicalConstruct node, HashSet <ILogicalConstruct> loopBody)
        {
            if (!loopBody.Contains(node))
            {
                //The node should be inside the loop.
                return(false);
            }


            if (node is ConditionLogicalConstruct)
            {
                HashSet <ISingleEntrySubGraph> nodeSuccessors = node.SameParentSuccessors;
                int insideBody = 0;
                foreach (ILogicalConstruct successor in nodeSuccessors)
                {
                    if (loopBody.Contains(successor))
                    {
                        insideBody++;
                    }
                }

                //There should be exactly one successor that is inside the body of the loop.
                return(insideBody == 1);
            }

            return(false);
        }
예제 #17
0
        /// <summary>
        /// Checks if single node can be in a loop. The loop is determined by <paramref name="loopHeader"/> and has <paramref name="nodesInLoop"/> for its body.
        /// </summary>
        /// <param name="node">The node in question.</param>
        /// <param name="nodesInLoop">The other nodes in the body of the loop.</param>
        /// <param name="loopHeader">The header of the loop.</param>
        /// <returns>Returns true, if <paramref name="node"/> can be in the loop.</returns>
        private bool CanBeInLoop(ILogicalConstruct node, ICollection <ILogicalConstruct> nodesInLoop, ILogicalConstruct loopHeader)
        {
            if (node == null)
            {
                return(false);
            }

            if (node == loopHeader)
            {
                /// The header is always part of the loop.
                return(true);
            }

            foreach (ISingleEntrySubGraph predecessor in node.SameParentPredecessors)
            {
                ILogicalConstruct predecessorLogicalConstruct = predecessor as ILogicalConstruct;
                if (predecessorLogicalConstruct == null)
                {
                    return(false);
                }

                HashSet <ILogicalConstruct> removedEdgesEnds;
                if (!nodesInLoop.Contains(predecessorLogicalConstruct) ||
                    (removedEdges.TryGetValue(predecessorLogicalConstruct, out removedEdgesEnds) && removedEdgesEnds.Contains(node)))
                {
                    /// The predecessor is not part of the loop.
                    /// Or it was marked for goto on earlier stage.
                    /// Either way this is multy-entry loop, which is not allowed
                    return(false);
                }
            }

            return(true);
        }
예제 #18
0
        /// <summary>
        /// The entry point of the builder.
        /// </summary>
        /// <param name="block">The logical construct, that is searched for loops.</param>
        public void BuildLoops(ILogicalConstruct block)
        {
            if (block.Children.Count == 0)
            {
                return;
            }

            foreach (ISingleEntrySubGraph child in block.Children)
            {
                //all children should be logical constructs
                ILogicalConstruct childConstruct = child as ILogicalConstruct;
                if (childConstruct == null)
                {
                    throw new ArgumentException("Child is not a logical construct.");
                }

                if (childConstruct is ConditionLogicalConstruct)
                {
                    //no loops should be found inside logical constructs
                    //this covers the rare case in which a single block is condition and body of the loop at the same time
                    continue;
                }

                /// Build the inner-most loops first.
                BuildLoops(childConstruct);
            }

            ProcessLogicalConstruct(block);
        }
 public void ProcessConstruct(ILogicalConstruct theConstruct)
 {
     if (theConstruct as CFGBlockLogicalConstruct != null || theConstruct as ConditionLogicalConstruct != null)
     {
         return;
     }
     if (theConstruct as BlockLogicalConstruct != null)
     {
         this.DetermineFollowNodesInSubGraph(theConstruct);
     }
     V_0 = theConstruct.get_Children().GetEnumerator();
     try
     {
         while (V_0.MoveNext())
         {
             V_1 = (ILogicalConstruct)V_0.get_Current();
             this.ProcessConstruct(V_1);
         }
     }
     finally
     {
         ((IDisposable)V_0).Dispose();
     }
     return;
 }
예제 #20
0
        private bool ArePredecessorsLegal(ILogicalConstruct node, HashSet <ILogicalConstruct> allowedPredecessors)
        {
            V_0 = node.get_SameParentPredecessors().GetEnumerator();
            try
            {
                while (V_0.MoveNext())
                {
                    V_1 = (ILogicalConstruct)V_0.get_Current();
                    if (allowedPredecessors.Contains(V_1))
                    {
                        continue;
                    }
                    V_2 = false;
                    goto Label1;
                }
                goto Label0;
            }
            finally
            {
                ((IDisposable)V_0).Dispose();
            }
Label1:
            return(V_2);

Label0:
            return(true);
        }
 /// <summary>
 /// Creates a new case logical construct that is not yet attached to the logical tree.
 /// </summary>
 /// <param name="entry"></param>
 public CaseLogicalConstruct(ILogicalConstruct entry)
 {
     this.Entry = entry;
     this.body  = new HashSet <ILogicalConstruct>();
     body.Add(entry);
     CaseNumbers = new List <int>();
 }
        /// <summary>
        /// Creates the loop body block.
        /// </summary>
        /// <param name="entry"></param>
        /// <param name="loopBodyNodes"></param>
        private void DetermineLoopBodyBlock(ILogicalConstruct entry, HashSet <ILogicalConstruct> loopBodyNodes)
        {
            this.LoopBodyBlock = null;
            if (loopBodyNodes.Count > 0)
            {
                if (this.LoopType != LoopType.PreTestedLoop)
                {
                    //If the loop is not pretested then the entry should be the entry of the loop body
                    if (!loopBodyNodes.Contains(entry))
                    {
                        //sanity check
                        throw new Exception("Invalid entry of loop body.");
                    }
                    this.LoopBodyBlock = new BlockLogicalConstruct(entry, loopBodyNodes);
                }
                else
                {
                    //Otherwise the entry should be the successor of the condition that is in the collection.
                    ILogicalConstruct loopBodyEntry = LoopCondition.TrueSuccessor;
                    if (loopBodyEntry == null || !loopBodyNodes.Contains(loopBodyEntry))
                    {
                        loopBodyEntry = LoopCondition.FalseSuccessor;
                    }

                    if (loopBodyEntry == null || !loopBodyNodes.Contains(loopBodyEntry))
                    {
                        //sanity check
                        throw new Exception("Invalid entry of loop body.");
                    }
                    this.LoopBodyBlock = new BlockLogicalConstruct(loopBodyEntry, loopBodyNodes);
                }
            }
        }
예제 #23
0
        /// <summary>
        /// The entry point of the builder.
        /// </summary>
        /// <param name="block">The logical construct, that is searched for loops.</param>
		public void BuildLoops(ILogicalConstruct block)
		{
			if (block.Children.Count == 0)
			{
				return;
			}

			foreach (ISingleEntrySubGraph child in block.Children)
			{
				//all children should be logical constructs
				ILogicalConstruct childConstruct = child as ILogicalConstruct;
				if (childConstruct == null)
				{
					throw new ArgumentException("Child is not a logical construct.");
				}

                if (childConstruct is ConditionLogicalConstruct)
                {
                    //no loops should be found inside logical constructs
                    //this covers the rare case in which a single block is condition and body of the loop at the same time
                    continue;
                }

                /// Build the inner-most loops first.
				BuildLoops(childConstruct);
			}

			ProcessLogicalConstruct(block);
		}
예제 #24
0
 public void BuildLoops(ILogicalConstruct block)
 {
     if (block.get_Children().get_Count() == 0)
     {
         return;
     }
     V_0 = block.get_Children().GetEnumerator();
     try
     {
         while (V_0.MoveNext())
         {
             V_1 = V_0.get_Current() as ILogicalConstruct;
             if (V_1 == null)
             {
                 throw new ArgumentException("Child is not a logical construct.");
             }
             if (V_1 as ConditionLogicalConstruct != null)
             {
                 continue;
             }
             this.BuildLoops(V_1);
         }
     }
     finally
     {
         ((IDisposable)V_0).Dispose();
     }
     this.ProcessLogicalConstruct(block);
     return;
 }
예제 #25
0
 private bool CanBePartOfComplexCondition(ILogicalConstruct node, HashSet <ILogicalConstruct> nodesInCondition, CFGBlockLogicalConstruct commonSuccessor)
 {
     if (node == null || node as ConditionLogicalConstruct == null || !this.ArePredecessorsLegal(node, nodesInCondition) || !node.get_CFGSuccessors().Contains(commonSuccessor))
     {
         return(false);
     }
     return(!nodesInCondition.Contains(node));
 }
 /// <summary>
 /// Determines whether the specified node can be added in a complex condition.
 /// </summary>
 /// <param name="node">The node that we want to add to the condition.</param>
 /// <param name="nodesInCondition">The nodes that are in the complex condition.</param>
 /// <param name="commonSuccessor">The supposed common successor.</param>
 /// <returns></returns>
 private bool CanBePartOfComplexCondition(ILogicalConstruct node, HashSet <ILogicalConstruct> nodesInCondition, CFGBlockLogicalConstruct commonSuccessor)
 {
     //In order to add the node to the condition it has to be a condition node. All of it's predecessors should be in the complex condition.
     //The node should have for successor the supposed common successor (the check is optimized). And the node should not be part of the complex
     //condition.
     return(node != null && node is ConditionLogicalConstruct && ArePredecessorsLegal(node, nodesInCondition) &&
            node.CFGSuccessors.Contains(commonSuccessor) && !nodesInCondition.Contains(node));
 }
예제 #27
0
 private ILogicalConstruct CheckSuccessor(ILogicalConstruct condition, ILogicalConstruct conditionSuccessor, HashSet <ISingleEntrySubGraph> otherSuccessorFrontier, DFSTree dfsTree)
 {
     if (otherSuccessorFrontier.Contains(conditionSuccessor) && !dfsTree.get_ConstructToNodeMap().TryGetValue(conditionSuccessor, out V_0) || dfsTree.get_ConstructToNodeMap().get_Item(condition).CompareTo(V_0) < 0)
     {
         return(conditionSuccessor);
     }
     return(null);
 }
        /// <summary>
        /// Fills <paramref name="interval"/> with the nodes, that belong to it.
        /// </summary>
        /// <param name="intervalHeader">The header node of <paramref name="interval"/>.</param>
        /// <param name="interval">The interval to be filled with nodes.</param>
        private void FillInterval(ILogicalConstruct intervalHeader, IntervalConstruct interval)
        {
            /// For more clarifications on the algorithm, see "6.3.3 Interval Theory" of <see cref="Reverse Compilation Techniques.pdf"/>.

            nodeToInterval.Add(intervalHeader, interval);
            Queue <ILogicalConstruct>       possibleNodes         = new Queue <ILogicalConstruct>();
            IEnumerable <ILogicalConstruct> currentNodeSuccessors = GetNodeSuccessors(intervalHeader);

            foreach (ILogicalConstruct successor in currentNodeSuccessors)
            {
                /// Check if the successor is from the graph that is being analysed
                /// This check is needed, because GetNodeSuccessors returns all successors, even the one that have been marked only as goto reachable.
                if (availableNodes.Contains(successor))
                {
                    possibleNodes.Enqueue(successor);
                }
            }

            while (possibleNodes.Count > 0)
            {
                ILogicalConstruct currentNode = possibleNodes.Dequeue();

                //check if the node is in any interval
                if (nodeToInterval.ContainsKey(currentNode))
                {
                    continue;
                }

                bool addInInterval = true;
                IEnumerable <ILogicalConstruct> currentNodePredecessorsCollection = GetNodePredecessors(currentNode);
                foreach (ILogicalConstruct predecessor in currentNodePredecessorsCollection)
                {
                    if (!nodeToInterval.ContainsKey(predecessor) || nodeToInterval[predecessor] != interval)
                    {
                        /// The construct has a predecessor, that is not from the current interval.
                        /// Thus, the construct is not dominated by the interval header, and isnt part of the interval
                        addInInterval = false;
                        break;
                    }
                }
                if (addInInterval)
                {
                    /// Add the node to the interval and update the corresponding collections.
                    interval.Children.Add(currentNode);
                    nodeToInterval.Add(currentNode, interval);
                    currentNodeSuccessors = GetNodeSuccessors(currentNode);

                    /// Update the possible nodes collection with all the successors of the current node.
                    foreach (ILogicalConstruct successor in currentNodeSuccessors)
                    {
                        if (availableNodes.Contains(successor))
                        {
                            possibleNodes.Enqueue(successor);
                        }
                    }
                }
            }
        }
 /// <param name="graph">The graph to be analyzed by the interval builder.</param>
 /// <param name="removedEdges">The edges in the Control flow graph, that have been marked as goto-edges.</param>
 public IntervalAnalyzer(ISingleEntrySubGraph graph, Dictionary<ILogicalConstruct, HashSet<ILogicalConstruct>> removedEdges)
 {
     this.availableNodes = graph.Children;
     this.entryPoint = graph.Entry as ILogicalConstruct;
     this.headers = new Queue<ILogicalConstruct>();
     this.intervals = new List<IntervalConstruct>();
     this.nodeToInterval = new Dictionary<ISingleEntrySubGraph, IntervalConstruct>();
     this.removedEdges = removedEdges;
 }
        /// <summary>
        /// Fills <paramref name="interval"/> with the nodes, that belong to it.
        /// </summary>
        /// <param name="intervalHeader">The header node of <paramref name="interval"/>.</param>
        /// <param name="interval">The interval to be filled with nodes.</param>
        private void FillInterval(ILogicalConstruct intervalHeader, IntervalConstruct interval)
        {
            /// For more clarifications on the algorithm, see "6.3.3 Interval Theory" of <see cref="Reverse Compilation Techniques.pdf"/>.

            nodeToInterval.Add(intervalHeader, interval);
            Queue<ILogicalConstruct> possibleNodes = new Queue<ILogicalConstruct>();
            IEnumerable<ILogicalConstruct> currentNodeSuccessors = GetNodeSuccessors(intervalHeader);
            foreach (ILogicalConstruct successor in currentNodeSuccessors)
            {
                /// Check if the successor is from the graph that is being analysed
                /// This check is needed, because GetNodeSuccessors returns all successors, even the one that have been marked only as goto reachable.
                if (availableNodes.Contains(successor))
                {
                    possibleNodes.Enqueue(successor);
                }
            }

            while (possibleNodes.Count > 0)
            {
                ILogicalConstruct currentNode = possibleNodes.Dequeue();

                //check if the node is in any interval
                if (nodeToInterval.ContainsKey(currentNode))
                {
                    continue;
                }

                bool addInInterval = true;
                IEnumerable<ILogicalConstruct> currentNodePredecessorsCollection = GetNodePredecessors(currentNode);
                foreach (ILogicalConstruct predecessor in currentNodePredecessorsCollection)
                {
                    if (!nodeToInterval.ContainsKey(predecessor) || nodeToInterval[predecessor] != interval)
                    {
                        /// The construct has a predecessor, that is not from the current interval.
                        /// Thus, the construct is not dominated by the interval header, and isnt part of the interval
                        addInInterval = false;
                        break;
                    }
                }
                if (addInInterval)
                {
                    /// Add the node to the interval and update the corresponding collections.
                    interval.Children.Add(currentNode);
                    nodeToInterval.Add(currentNode, interval);
                    currentNodeSuccessors = GetNodeSuccessors(currentNode);

                    /// Update the possible nodes collection with all the successors of the current node.
                    foreach (ILogicalConstruct successor in currentNodeSuccessors)
                    {
                        if (availableNodes.Contains(successor))
                        {
                            possibleNodes.Enqueue(successor);
                        }
                    }
                }
            }
        }
 protected DominatorTree GetDominatorTreeFromContext(ILogicalConstruct construct)
 {
     if (!this.logicalContext.get_LogicalConstructToDominatorTreeMap().TryGetValue(construct, out V_0))
     {
         V_0 = FastDominatorTreeBuilder.BuildTree(construct);
         this.logicalContext.get_LogicalConstructToDominatorTreeMap().Add(construct, V_0);
     }
     return(V_0);
 }
 public CaseLogicalConstruct(ILogicalConstruct entry)
 {
     base();
     this.set_Entry(entry);
     this.body = new HashSet <ILogicalConstruct>();
     dummyVar0 = this.body.Add(entry);
     this.set_CaseNumbers(new List <int>());
     return;
 }
 /// <summary>
 /// Builds if constructs in the specified construct.
 /// </summary>
 /// <param name="construct"></param>
 private void BuildIfConstructs(ILogicalConstruct construct)
 {
     DominatorTree dominatorTree = GetDominatorTreeFromContext(construct);
     DFSTree dfsTree = DFSTBuilder.BuildTree(construct);
     foreach (ConditionLogicalConstruct condition in GetPostOrderedIfConditionCandidates(dfsTree))
     {
         TryBuildIfConstruct(condition, dominatorTree, dfsTree);
     }
 }
예제 #34
0
        /// <summary>
        /// Returns the closest guarded block (try/catch/filter/fault/finally) that encloses the given construct.
        /// </summary>
        /// <param name="start">The construct for which the guarded block parent should be found</param>
        /// <returns></returns>
        public static BlockLogicalConstruct GetNearestGuardedBlock(ILogicalConstruct start)
        {
            ILogicalConstruct nearestGuardedBlockCandidate = start;

            while (nearestGuardedBlockCandidate != null &&
                   !(nearestGuardedBlockCandidate is ExceptionHandlingLogicalConstruct))
            {
                nearestGuardedBlockCandidate = (ILogicalConstruct)nearestGuardedBlockCandidate.Parent;
            }

            if (nearestGuardedBlockCandidate == null)
            {
                return(null);
            }

            if ((nearestGuardedBlockCandidate as ExceptionHandlingLogicalConstruct).Try.CFGBlocks.Contains(start.FirstBlock))
            {
                return((nearestGuardedBlockCandidate as ExceptionHandlingLogicalConstruct).Try);
            }

            if (nearestGuardedBlockCandidate is TryCatchFilterLogicalConstruct)
            {
                TryCatchFilterLogicalConstruct tcf = nearestGuardedBlockCandidate as TryCatchFilterLogicalConstruct;
                foreach (IFilteringExceptionHandler handler in tcf.Handlers)
                {
                    if (handler.HandlerType == FilteringExceptionHandlerType.Filter)
                    {
                        if ((handler as ExceptionHandlingBlockFilter).Filter.CFGBlocks.Contains(start.FirstBlock))
                        {
                            return((handler as ExceptionHandlingBlockFilter).Filter);
                        }
                        else
                        {
                            return((handler as ExceptionHandlingBlockFilter).Handler);
                        }
                    }
                    else if (handler.HandlerType == FilteringExceptionHandlerType.Catch)
                    {
                        return(handler as ExceptionHandlingBlockCatch);
                    }
                }
            }
            else if (nearestGuardedBlockCandidate is TryFinallyLogicalConstruct)
            {
                return((nearestGuardedBlockCandidate as TryFinallyLogicalConstruct).Finally);
            }
            else if (nearestGuardedBlockCandidate is TryFaultLogicalConstruct)
            {
                return((nearestGuardedBlockCandidate as TryFaultLogicalConstruct).Fault);
            }
            else
            {
                throw new Exception("Unknown type of exception handling logical construct encountered.");
            }

            return(null);
        }
 /// <param name="graph">The graph to be analyzed by the interval builder.</param>
 /// <param name="removedEdges">The edges in the Control flow graph, that have been marked as goto-edges.</param>
 public IntervalAnalyzer(ISingleEntrySubGraph graph, Dictionary <ILogicalConstruct, HashSet <ILogicalConstruct> > removedEdges)
 {
     this.availableNodes = graph.Children;
     this.entryPoint     = graph.Entry as ILogicalConstruct;
     this.headers        = new Queue <ILogicalConstruct>();
     this.intervals      = new List <IntervalConstruct>();
     this.nodeToInterval = new Dictionary <ISingleEntrySubGraph, IntervalConstruct>();
     this.removedEdges   = removedEdges;
 }
		/// <summary>
		/// Returns the closest guarded block (try/catch/filter/fault/finally) that encloses the given construct.
		/// </summary>
		/// <param name="start">The construct for which the guarded block parent should be found</param>
		/// <returns></returns>
		public static BlockLogicalConstruct GetNearestGuardedBlock(ILogicalConstruct start)
		{
			ILogicalConstruct nearestGuardedBlockCandidate = start;
			while (nearestGuardedBlockCandidate != null &&
				  !(nearestGuardedBlockCandidate is ExceptionHandlingLogicalConstruct))
			{
				nearestGuardedBlockCandidate = (ILogicalConstruct)nearestGuardedBlockCandidate.Parent;
			}

			if (nearestGuardedBlockCandidate == null)
			{
				return null;
			}

			if ((nearestGuardedBlockCandidate as ExceptionHandlingLogicalConstruct).Try.CFGBlocks.Contains(start.FirstBlock))
			{
				return (nearestGuardedBlockCandidate as ExceptionHandlingLogicalConstruct).Try;
			}

			if (nearestGuardedBlockCandidate is TryCatchFilterLogicalConstruct)
			{
				TryCatchFilterLogicalConstruct tcf = nearestGuardedBlockCandidate as TryCatchFilterLogicalConstruct;
				foreach(IFilteringExceptionHandler handler in tcf.Handlers)
				{
					if (handler.HandlerType == FilteringExceptionHandlerType.Filter)
					{
						if ((handler as ExceptionHandlingBlockFilter).Filter.CFGBlocks.Contains(start.FirstBlock))
						{
							return (handler as ExceptionHandlingBlockFilter).Filter;
						}
						else
						{
							return (handler as ExceptionHandlingBlockFilter).Handler;
						}
					}
					else if (handler.HandlerType == FilteringExceptionHandlerType.Catch)
					{
						return handler as ExceptionHandlingBlockCatch;
					}
				}
			}
			else if (nearestGuardedBlockCandidate is TryFinallyLogicalConstruct)
			{
				return (nearestGuardedBlockCandidate as TryFinallyLogicalConstruct).Finally;
			}
			else if (nearestGuardedBlockCandidate is TryFaultLogicalConstruct)
			{
				return (nearestGuardedBlockCandidate as TryFaultLogicalConstruct).Fault;
			}
			else
			{
				throw new Exception("Unknown type of exception handling logical construct encountered.");
			}

			return null;
		}
 private void ProcessSwitchConstructs(ILogicalConstruct parent, List<CFGBlockLogicalConstruct> switchBlocks)
 {
     DominatorTree dominatorTree = GetDominatorTreeFromContext(parent);
     DFSTree dfsTree = DFSTBuilder.BuildTree(parent);
     switchBlocks.Sort((x, y) => dfsTree.ConstructToNodeMap[y].ReversePostOrderIndex.CompareTo(dfsTree.ConstructToNodeMap[x].ReversePostOrderIndex));
     foreach (CFGBlockLogicalConstruct switchBlock in switchBlocks)
     {
         CreateSwitchConstruct(switchBlock, parent, this.logicalContext.CFG.SwitchBlocksInformation[switchBlock.TheBlock], dominatorTree);
     }
 }
        protected DominatorTree GetDominatorTreeFromContext(ILogicalConstruct construct)
        {
            DominatorTree result;
            if (!logicalContext.LogicalConstructToDominatorTreeMap.TryGetValue(construct, out result))
            {
                result = FastDominatorTreeBuilder.BuildTree(construct);
                logicalContext.LogicalConstructToDominatorTreeMap.Add(construct, result);
            }

            return result;
        }
        /// <summary>
        /// Creates a collection holding all the children (to be) of the construct.
        /// </summary>
        /// <returns></returns>
        private ICollection<ILogicalConstruct> GetBodyCollection()
        {
            int additionalNodes = this.DefaultCase != null ? 2 : 1;
            ILogicalConstruct[] switchBody = new ILogicalConstruct[this.ConditionCases.Length + additionalNodes];
            Array.Copy(this.ConditionCases, switchBody, this.ConditionCases.Length);
            switchBody[switchBody.Length - additionalNodes] = this.Entry as ILogicalConstruct;
            if (additionalNodes == 2)
            {
                switchBody[switchBody.Length - 1] = this.DefaultCase;
            }

            return switchBody;
        }
        /// <summary>
        /// Builds if constructs in the specified construct and all of it's children.
        /// </summary>
        /// <param name="construct"></param>
        public void BuildConstructs(ILogicalConstruct construct)
        {
            if(construct is CFGBlockLogicalConstruct || construct is ConditionLogicalConstruct)
            {
                return;
            }

            foreach (ILogicalConstruct child in construct.Children)
            {
                BuildConstructs(child);
            }

            BuildIfConstructs(construct);
        }
        /// <summary>
        /// Traverses the graph and tries to merge conditions into complex condition constructs.
        /// </summary>
        /// <param name="theConstruct"></param>
        /// <returns>Returns true if there was a successful merge.</returns>
        private bool TryTraverseAndMerge(ILogicalConstruct theConstruct)
        {
            //The algorithm is split into iterations, because once it merges a complex condition this condition can be used with one of
            //its predecessors to create another complex condition. This means that special modifications are needed to the traversal,
            //which may lead to bugs and is overall more hard to maintain.

            //We use BFS to traverse the subgraph
            HashSet<ILogicalConstruct> traversedNodes = new HashSet<ILogicalConstruct>();
            Queue<ILogicalConstruct> traverseQueue = new Queue<ILogicalConstruct>();
            traverseQueue.Enqueue(theConstruct.Entry as ILogicalConstruct);
            bool changed = false;

            while (traverseQueue.Count > 0)
            {
                ILogicalConstruct currentNode = traverseQueue.Dequeue();
                
                //For each node that is a condition construct we try to create a complex condition starting from it
                ConditionLogicalConstruct currentConditionNode = currentNode as ConditionLogicalConstruct;
                if(currentConditionNode != null)
                {
                    ConditionLogicalConstruct newNode = CreateComplexCondition(currentConditionNode);

                    //If we succeed we mark that there was a change in the subgraph;
                    changed |= newNode != currentNode;

                    //We change the currentNode to the newNode since if there was a merge then the currentNode will be a successor of the newNode
                    currentNode = newNode;
                }

                //We mark the current node as traversed
                traversedNodes.Add(currentNode);

                //Normal bfs continues
                foreach (ILogicalConstruct successor in currentNode.SameParentSuccessors)
                {
                    if(!traversedNodes.Contains(successor))
                    {
                        traverseQueue.Enqueue(successor);
                    }
                }

                while(traverseQueue.Count > 0 && traversedNodes.Contains(traverseQueue.Peek()))
                {
                    traverseQueue.Dequeue();
                }
            }

            return changed;
        }
예제 #42
0
        /// <summary>
        /// Generates the loops in the graph with entry point <paramref name="construct"/>.
        /// </summary>
        /// <param name="construct">The entry point of the graph.</param>
        private void ProcessLogicalConstruct(ILogicalConstruct construct)
		{
            DominatorTree dominatorTree = GetDominatorTreeFromContext(construct);
			int lastIterationIntervalsCount = int.MaxValue;

            RemoveBackEdgesFromSwitchConstructs(construct);

			while (lastIterationIntervalsCount > 1)
			{
				IntervalAnalyzer ia = new IntervalAnalyzer(construct, removedEdges);
				List<IntervalConstruct> intervals = ia.ReduceCfg();

                List<IntervalConstruct> reverseIntervals = new List<IntervalConstruct>(intervals);
                reverseIntervals.Reverse();

                /// Make only one loop at a time, since the newly made loop can be the header node of a bigger loop (if they are nested so).
				bool madeLoop = false;
				foreach (IntervalConstruct interval in reverseIntervals)
				{
                    if (TryMakeLoop(interval, dominatorTree))
                    {
                        madeLoop = true;
                        break;
                    }
				}

                if(madeLoop)
                {
                    lastIterationIntervalsCount = intervals.Count;
                    continue;
                }

                /// No loop was made in the last iteration and the interval count wasn't reduced. Then, an edge must be deleted from the graph, 
                /// to ensure the reducibility.
				if (intervals.Count == lastIterationIntervalsCount)
				{
					RemoveBlockingEdges(intervals);
				}

                /// This is sanity check. Intervals are supposed to decrease in count, or stay the same with each iteration
                if (intervals.Count > lastIterationIntervalsCount)
				{
					throw new Exception("Intervails are more than in the last iteration.");
				}

				lastIterationIntervalsCount = intervals.Count;
			}
		}
        /// <summary>
        /// Recursively determines the follow nodes of all logical constructs in the given construct.
        /// </summary>
        /// <remarks>
        /// We need to determine only the follow nodes of the constructs that are children of block logical constructs. In every other construct
        /// the order is determined by the type of the construct.
        /// </remarks>
        /// <param name="theConstruct"></param>
        public void ProcessConstruct(ILogicalConstruct theConstruct)
        {
            if(theConstruct is CFGBlockLogicalConstruct || theConstruct is ConditionLogicalConstruct)
            {
                return;
            }

            if (theConstruct is BlockLogicalConstruct)
            {
                DetermineFollowNodesInSubGraph(theConstruct);
            }

            foreach (ILogicalConstruct child in theConstruct.Children)
            {
                ProcessConstruct(child);
            }
        }
        private void CreateSwitchConstruct(CFGBlockLogicalConstruct switchBlock, ILogicalConstruct parentConstruct,
            SwitchData switchData, DominatorTree dominatorTree)
        {
            List<KeyValuePair<CFGBlockLogicalConstruct, List<int>>> cfgSuccessorToLabelsMap = GetOrderedCFGSuccessorToLabelsMap(switchData);
            Dictionary<ILogicalConstruct, HashSet<ISingleEntrySubGraph>> validCaseEntryToDominatedNodesMap = GetValidCases(dominatorTree, switchBlock);

            List<CaseLogicalConstruct> orderedCaseConstructs = new List<CaseLogicalConstruct>();
            PairList<List<int>, CFGBlockLogicalConstruct> labelsToCFGSuccessorsList = new PairList<List<int>, CFGBlockLogicalConstruct>();
            foreach (KeyValuePair<CFGBlockLogicalConstruct, List<int>> cfgSuccessorToLabelsPair in cfgSuccessorToLabelsMap)
            {
                ILogicalConstruct successor;
                HashSet<ISingleEntrySubGraph> dominatedNodes;
                if (LogicalFlowUtilities.TryGetParentConstructWithGivenParent(cfgSuccessorToLabelsPair.Key, parentConstruct, out successor) &&
                    validCaseEntryToDominatedNodesMap.TryGetValue(successor, out dominatedNodes))
                {
                    CaseLogicalConstruct newCaseConstruct = new CaseLogicalConstruct(successor);
                    newCaseConstruct.CaseNumbers.AddRange(cfgSuccessorToLabelsPair.Value);
                    newCaseConstruct.Body.UnionWith(dominatedNodes.Cast<ILogicalConstruct>());
                    newCaseConstruct.AttachCaseConstructToGraph();
                    orderedCaseConstructs.Add(newCaseConstruct);
                }
                else
                {
                    labelsToCFGSuccessorsList.Add(cfgSuccessorToLabelsPair.Value, cfgSuccessorToLabelsPair.Key);
                }
            }

            CaseLogicalConstruct defaultCase = null;
            CFGBlockLogicalConstruct defaultCFGSuccessor = GetCFGLogicalConstructFromBlock(switchData.DefaultCase);
            ILogicalConstruct defaultSuccessor;
            HashSet<ISingleEntrySubGraph> defaultCaseNodes;
            if (LogicalFlowUtilities.TryGetParentConstructWithGivenParent(defaultCFGSuccessor, parentConstruct, out defaultSuccessor) &&
                    validCaseEntryToDominatedNodesMap.TryGetValue(defaultSuccessor, out defaultCaseNodes))
            {
                defaultCase = new CaseLogicalConstruct(defaultSuccessor);
                if (HasSuccessors(defaultCaseNodes))
                {
                    defaultCase.Body.UnionWith(defaultCaseNodes.Cast<ILogicalConstruct>());
                }
                defaultCase.AttachCaseConstructToGraph();
            }

            SwitchLogicalConstruct theSwitch = SwitchLogicalConstruct.GroupInSwitchConstruct(switchBlock, orderedCaseConstructs, labelsToCFGSuccessorsList, defaultCase, defaultCFGSuccessor);
            UpdateDominatorTree(dominatorTree, theSwitch);
        }
        /// <summary>
        /// Merges the simple condition constructs into complex condition constructs representing a short-circuit boolean expression.
        /// </summary>
        /// <param name="theConstruct"></param>
        private void CreateComplexConditions(ILogicalConstruct theConstruct)
        {
            //If the construct is ConditionLC then there is no need to traverse it.
            if(theConstruct is ConditionLogicalConstruct || theConstruct is CFGBlockLogicalConstruct)
            {
                return;
            }

            foreach (ILogicalConstruct child in theConstruct.Children)
            {
                CreateComplexConditions(child);
            }

            //Each iteration tries to find and merge new condition constructs together.
            bool mergedCondition;
            do
            {
                mergedCondition = TryTraverseAndMerge(theConstruct);
            }
            while (mergedCondition);
        }
        /// <summary>
        /// Determines the follow nodes in the given subgraph.
        /// </summary>
        /// <remarks>
        /// Every node can follow only one node.
        /// Everey node can be followed by only one node.
        /// The follow node relation cannot form a back edge. (i.e. B can be the follow node of A <=> (A, B) is not a backedge)
        /// Let G = (V, E) be the original graph.
        /// Let G' = (V, E') be the subgraph of G, where E' = E \ { e | e is from E && e is backedge in the DFS traversal }.
        /// 
        /// The solution is to find a cover of vertex-disjoint paths of G' that will yield the minimum number of gotos.
        /// The gotos will be the edges that are not in the cover. So we want the edges that will yeild the greatest number of gotos to
        /// be in the cover. If we find a good weight function for the edges in the graph (i.e. correctly determines how much gotos there will be between
        /// two nodes), then all we have to do is find a cover of vertex-disjoint paths of G' with maximum total weight.
        /// </remarks>
        /// <param name="theGraph"></param>
        private void DetermineFollowNodesInSubGraph(ILogicalConstruct theGraph)
        {
            //Creates the adjacency matrix for the mentioned subgraph - G'.
            GetVerticesAndAdjacencyMatrix(theGraph);

            //Since no back edge is left in G', then G' is a DAG.
            List<KeyValuePair<int, int>> followEdges = MaxWeightDisjointPathsFinder.GetOptimalEdgesInDAG(adjacencyMatrix);

            foreach (KeyValuePair<int, int> followEdge in followEdges)
            {
                orderedVertexArray[followEdge.Key].CFGFollowNode = orderedVertexArray[followEdge.Value].FirstBlock;
                if(orderedVertexArray[followEdge.Key] is ConditionLogicalConstruct)
                {
                    ConditionLogicalConstruct theCondition = orderedVertexArray[followEdge.Key] as ConditionLogicalConstruct;
                    if(theCondition.CFGFollowNode == theCondition.TrueCFGSuccessor)
                    {
                        //If the follow node of a condition construct is the true successor, then we need to negate the condition construct.
                        theCondition.Negate(typeSystem);
                    }
                }
            }
        }
        /// <summary>
        /// Creates a new loop construct and attaches it to the logical tree.
        /// </summary>
        /// <param name="entry">The entry to the loop construct.</param>
        /// <param name="loopBody">Collection containing all of the constructs in the loop body.</param>
        /// <param name="loopType">The type of the loop.</param>
        /// <param name="loopCondition">The condition of the loop.</param>
        public LoopLogicalConstruct(ILogicalConstruct entry,
            HashSet<ILogicalConstruct> loopBody, LoopType loopType, ConditionLogicalConstruct loopCondition, TypeSystem typeSystem)
        {
			if (loopCondition != null)
			{
				loopCondition.LogicalContainer = this;
			}

            LoopType = loopType;
            LoopCondition = loopCondition;
            
            if(this.LoopType != LoopType.InfiniteLoop)
            {
                loopBody.Remove(LoopCondition);
            }

            DetermineLoopBodyBlock(entry, loopBody);

            RedirectChildrenToNewParent(GetLoopChildrenCollection());

            FixLoopCondition(typeSystem);
        }
        private void ProcessGotoFlowConstructs(BlockLogicalConstruct theConstruct)
        {
            ILogicalConstruct[] sortedChildren = new ILogicalConstruct[theConstruct.Children.Count];
            int index = 0;
            foreach (ILogicalConstruct child in theConstruct.Children)
            {
                sortedChildren[index++] = child;
            }
            Array.Sort<ISingleEntrySubGraph>(sortedChildren);

            HashSet<ILogicalConstruct> usedAsFollow = new HashSet<ILogicalConstruct>();
            foreach (ILogicalConstruct currentChild in sortedChildren)
            {
                if(visitedConstructs.Add(currentChild))
                {
                    if (visitedConstructs.Contains(currentChild.FollowNode) || !usedAsFollow.Add(currentChild.FollowNode))
                    {
                        currentChild.CFGFollowNode = null;
                    }

                    ProcessLogicalConstruct(currentChild);
                }
            }
        }
		private void ProcessLogicalConstruct(ILogicalConstruct theConstruct)
		{
			if (theConstruct is BlockLogicalConstruct)
			{
				ILogicalConstruct current = (ILogicalConstruct)theConstruct.Entry;
				while (current != null)
				{
					ProcessLogicalConstruct(current);
					if(visitedConstructs.Contains(current.FollowNode))
					{
						current.CFGFollowNode = null;
					}
					current = current.FollowNode;
				}

                ProcessGotoFlowConstructs(theConstruct as BlockLogicalConstruct);
			}
			else if (theConstruct is ExceptionHandlingLogicalConstruct)
			{
				ProcessLogicalConstruct((theConstruct as ExceptionHandlingLogicalConstruct).Try);
				if (theConstruct is TryCatchFilterLogicalConstruct)
				{
					foreach (IFilteringExceptionHandler handler in (theConstruct as TryCatchFilterLogicalConstruct).Handlers)
					{
						if (handler.HandlerType == FilteringExceptionHandlerType.Filter)
						{
							ProcessLogicalConstruct((handler as ExceptionHandlingBlockFilter).Filter);
							ProcessLogicalConstruct((handler as ExceptionHandlingBlockFilter).Handler);
						}
						else if (handler.HandlerType == FilteringExceptionHandlerType.Catch)
						{
							ProcessLogicalConstruct((handler as ExceptionHandlingBlockCatch));
						}
					}
				}
				else if (theConstruct is TryFaultLogicalConstruct)
				{
					ProcessLogicalConstruct((theConstruct as TryFaultLogicalConstruct).Fault);
				}
				else if (theConstruct is TryFinallyLogicalConstruct)
				{
					ProcessLogicalConstruct((theConstruct as TryFinallyLogicalConstruct).Finally);
				}
			}
			else if (theConstruct is IfLogicalConstruct)
			{
				IfLogicalConstruct theIf = theConstruct as IfLogicalConstruct;
				ProcessLogicalConstruct(theIf.Then);
				if (theIf.Else != null)
				{
					ProcessLogicalConstruct(theIf.Else);
				}
			}
			else if (theConstruct is LoopLogicalConstruct)
			{
				LoopLogicalConstruct theLogicalLoop = theConstruct as LoopLogicalConstruct;
				ProcessLogicalConstruct(theLogicalLoop.LoopBodyBlock);
				ProcessLogicalConstruct(theLogicalLoop.LoopCondition);
			}
			else if (theConstruct is SwitchLogicalConstruct)
			{
				SwitchLogicalConstruct theLogicalSwitch = theConstruct as SwitchLogicalConstruct;
				foreach(CaseLogicalConstruct @case in theLogicalSwitch.ConditionCases)
				{
					ProcessLogicalConstruct(@case);
				}
                ProcessLogicalConstruct(theLogicalSwitch.DefaultCase);
			}
			else if (theConstruct is ConditionLogicalConstruct)
			{
				ConditionLogicalConstruct clc = theConstruct as ConditionLogicalConstruct;
				ProcessLogicalConstruct(clc.FirstBlock);
			}

			visitedConstructs.Add(theConstruct);
		}
예제 #50
0
        /// <summary>
        /// Removes back edges from switch blocks. Switch cases can not form a loop. If the control flow forms a loop, it should be represented by goto-label contructs.
        /// </summary>
        /// <param name="theConstruct">The construct, that might contain switches.</param>
        private void RemoveBackEdgesFromSwitchConstructs(ILogicalConstruct theConstruct)
        {
            DFSTree dfsTree = DFSTBuilder.BuildTree(theConstruct);
            foreach (DFSTEdge edge in dfsTree.BackEdges)
            {
                ILogicalConstruct startConstruct = edge.Start.Construct as ILogicalConstruct;
                if (startConstruct is ConditionLogicalConstruct)
                {
                    continue;
                }

                CFGBlockLogicalConstruct startCfgConstruct = startConstruct as CFGBlockLogicalConstruct;
                if((startCfgConstruct != null && startCfgConstruct.TheBlock.Last.OpCode.Code == Mono.Cecil.Cil.Code.Switch))
                {
                    MarkAsGotoEdge(startConstruct, edge.End.Construct as ILogicalConstruct);
                }
            }
        }
예제 #51
0
        /// <summary>
        /// Checks if single node can be in a loop. The loop is determined by <paramref name="loopHeader"/> and has <paramref name="nodesInLoop"/> for its body.
        /// </summary>
        /// <param name="node">The node in question.</param>
        /// <param name="nodesInLoop">The other nodes in the body of the loop.</param>
        /// <param name="loopHeader">The header of the loop.</param>
        /// <returns>Returns true, if <paramref name="node"/> can be in the loop.</returns>
		private bool CanBeInLoop(ILogicalConstruct node, ICollection<ILogicalConstruct> nodesInLoop, ILogicalConstruct loopHeader)
		{
			if (node == null)
			{
				return false;
			}

			if (node == loopHeader)
			{
                /// The header is always part of the loop.
				return true;
			}

			foreach (ISingleEntrySubGraph predecessor in node.SameParentPredecessors)
			{
				ILogicalConstruct predecessorLogicalConstruct = predecessor as ILogicalConstruct;
				if (predecessorLogicalConstruct == null)
				{
					return false;
				}

                HashSet<ILogicalConstruct> removedEdgesEnds;
                if (!nodesInLoop.Contains(predecessorLogicalConstruct) ||
                    (removedEdges.TryGetValue(predecessorLogicalConstruct, out removedEdgesEnds) && removedEdgesEnds.Contains(node)))
				{
                    /// The predecessor is not part of the loop.
                    /// Or it was marked for goto on earlier stage.
					/// Either way this is multy-entry loop, which is not allowed
					return false;
				}
			}

			return true;
		}
		ILogicalConstruct FindChildBlockBelongsTo(ILogicalConstruct parent, CFGBlockLogicalConstruct block)
		{
			ILogicalConstruct result = null, current = block;

			do
			{
				if (current.Parent == parent)
				{
					result = current;
					break;
				}

				current = (ILogicalConstruct)current.Parent;

			} while (current.Parent != null);

			return result;
		}
		private HashSet<ILogicalConstruct> GetLogicalConstructsInRange(BlockRange blockRange, out ILogicalConstruct theCommonParent)
		{
			HashSet<ILogicalConstruct> children = new HashSet<ILogicalConstruct>();
			HashSet<ISingleEntrySubGraph> blocksParents = new HashSet<ISingleEntrySubGraph>();

            int rangeBegin = blockRange.Start.First.Offset;
            int rangeEnd = blockRange.End.First.Offset;
            for (int i = 0; i < context.CFG.Blocks.Length; i++)
            {
                InstructionBlock currentBlock = context.CFG.Blocks[i];
                if(currentBlock.First.Offset >= rangeBegin && currentBlock.First.Offset <= rangeEnd)
                {
                    CFGBlockLogicalConstruct[] cfgConstructs = context.CFGBlockToLogicalConstructMap[currentBlock];

                    for (int j = 0; j < cfgConstructs.Length; j++)
                    {
                        blocksParents.Add((ILogicalConstruct)cfgConstructs[j].Parent);
                        children.Add(cfgConstructs[j]);
                    }
                }
            }

			if (blocksParents.Count == 1)
			{
				theCommonParent = (ILogicalConstruct)blocksParents.ToArray<ISingleEntrySubGraph>()[0];

				return children;
			}
				//TODO: CCheck whether the parent logical construct of of each CFGBlockLogicalConstruct that belongs to the exception handling block,
				//(i.e. each member of blocksParents) contains as children ONLY blocks that belong to the exception handling block (i.e. blocks that are in blockRange).

			theCommonParent = (ILogicalConstruct)LogicalFlowUtilities.FindFirstCommonParent(blocksParents);

			HashSet<ILogicalConstruct> result = new HashSet<ILogicalConstruct>();
            foreach (ILogicalConstruct child in children)
            {
                ILogicalConstruct desiredNode;
                LogicalFlowUtilities.TryGetParentConstructWithGivenParent(child, theCommonParent, out desiredNode);
                result.Add(desiredNode);
            }

            if (theCommonParent is ExceptionHandlingLogicalConstruct)
            {
                result.Clear();
                result.Add(theCommonParent);
                theCommonParent = theCommonParent.Parent as ILogicalConstruct;
            }

			return result;
		}
예제 #54
0
        /// <summary>
        /// Gets the successors (direct or indirect) of the given <paramref name="startNode"/>,
        /// that are in the specified <paramref name="interval"/>.
        /// </summary>
        /// <remarks>
        /// If the start node is not in the interval, then it will not be traversed. This is a corner case for entwined loops.
        /// The start node will not be included in the result, even if it is its own successor.
        /// </remarks>
        /// <returns></returns>
        private HashSet<ILogicalConstruct> GetIntervalSuccessors(IntervalConstruct interval, ILogicalConstruct startNode)
        {
            HashSet<ILogicalConstruct> intervalSuccessors = new HashSet<ILogicalConstruct>();
            if (!interval.Children.Contains(startNode))
            {
                return intervalSuccessors;
            }

            Queue<ILogicalConstruct> traversalQueue = new Queue<ILogicalConstruct>();
            traversalQueue.Enqueue(startNode);
            HashSet<ILogicalConstruct> traversedNodes = new HashSet<ILogicalConstruct>();
            traversedNodes.Add(startNode);

            while(traversalQueue.Count > 0)
            {
                ILogicalConstruct currentNode = traversalQueue.Dequeue();
                foreach (ILogicalConstruct successor in currentNode.SameParentSuccessors)
                {
                    if(!traversedNodes.Contains(successor) && interval.Children.Contains(successor) && intervalSuccessors.Add(successor))
                    {
                        traversedNodes.Add(successor);
                        traversalQueue.Enqueue(successor);
                    }
                }
            }

            return intervalSuccessors;
        }
예제 #55
0
        /// <summary>
        /// Marks the edge between <paramref name="start"/> and <paramref name="end"/> as goto.
        /// </summary>
        /// <param name="start">The starting construct of the edge.</param>
        /// <param name="end">The ending construct of the edge.</param>
		private void MarkAsGotoEdge(ILogicalConstruct start, ILogicalConstruct end)
		{
            /// We assume, that all edges that will be marked as Goto are between CFGBlockLogicalConstruct nodes.
            /// If at some later stage it's evident that this case may arrise between constructs, different from CFGBlocks, then the implementation
            /// must be changed in a way, that ensures that the goto-links are transfered down the logical tree to the CfgBlocks.
            if (start == null || end == null)
			{
				throw new System.ArgumentOutOfRangeException("GoTo edge's ends must implement ILogicalConstruct.");
			}

            HashSet<ILogicalConstruct> removedSuccessors;
            if(!removedEdges.TryGetValue(start, out removedSuccessors))
            {
                removedSuccessors = new HashSet<ILogicalConstruct>();
                removedEdges[start] = removedSuccessors;
            }

            removedSuccessors.Add(end);
		}
예제 #56
0
        /// <summary>
        /// Adds all of the nodes from the <paramref name="interval"/>, that are not preceded by the <paramref name="loopSuccessor"/>,
        /// to the <paramref name="loopBody"/>.
        /// </summary>
        /// <remarks>
        /// Does not add the <paramref name="loopSuccessor"/>.
        /// </remarks>
        private void ExpandLoopBody(IntervalConstruct interval, HashSet<ILogicalConstruct> loopBody, ILogicalConstruct loopSuccessor)
        {
            HashSet<ILogicalConstruct> nodesToSkip = GetIntervalSuccessors(interval, loopSuccessor);
            nodesToSkip.Add(loopSuccessor);

            foreach (LogicalConstructBase node in interval.Children)
            {
                if (!nodesToSkip.Contains(node))
                {
                    loopBody.Add(node);
                }
            }
        }
예제 #57
0
        /// <summary>
        /// Determines whether the specified <paramref name="node"/> can be a condition to the loop with body - <paramref name="loopBody"/>.
        /// </summary>
        /// <param name="node">The possible condition node.</param>
        /// <param name="loopBody">The body of the loop.</param>
        /// <returns>Returns true, if <paramref name="node"/> can be the condition of the loop.</returns>
        private bool CanBeLoopCondition(ILogicalConstruct node, HashSet<ILogicalConstruct> loopBody)
        {
            if(!loopBody.Contains(node))
            {
                //The node should be inside the loop.
                return false;
            }

            
            if(node is ConditionLogicalConstruct)
            {
                HashSet<ISingleEntrySubGraph> nodeSuccessors = node.SameParentSuccessors;
                int insideBody = 0;
                foreach (ILogicalConstruct successor in nodeSuccessors)
                {
                    if (loopBody.Contains(successor))
                    {
                        insideBody++;
                    }
                }

                //There should be exactly one successor that is inside the body of the loop.
                return insideBody == 1;
            }

            return false;
        }
예제 #58
0
        /// <summary>
        /// Returns the condition loop exit with the greatest post order index, that has the <paramref name="loopSuccessor"/> as successor.
        /// </summary>
        /// <param name="dfsTree"></param>
        /// <param name="loopBody"></param>
        /// <param name="loopExits"></param>
        /// <param name="loopSuccessor"></param>
        /// <returns></returns>
        private ConditionLogicalConstruct GetLoopConditionWithMaxIndex(DFSTree dfsTree, HashSet<ILogicalConstruct> loopBody, HashSet<ILogicalConstruct> loopExits,
            ILogicalConstruct loopSuccessor)
        {
            int maxOrderIndexOfExit = -1;
            foreach (ILogicalConstruct loopExit in loopExits)
            {
                int currentOrderIndex = dfsTree.ConstructToNodeMap[loopExit].ReversePostOrderIndex;
                if (loopExit.SameParentSuccessors.Contains(loopSuccessor) && currentOrderIndex > maxOrderIndexOfExit && CanBeLoopCondition(loopExit, loopBody))
                {
                    maxOrderIndexOfExit = currentOrderIndex;
                }
            }

            if(maxOrderIndexOfExit > -1)
            {
                return dfsTree.ReversePostOrder[maxOrderIndexOfExit].Construct as ConditionLogicalConstruct;
            }

            return null;
        }
 public BlockLogicalConstruct(ILogicalConstruct Entry, IEnumerable<ILogicalConstruct> body)
 {
     this.Entry = Entry;
     
     RedirectChildrenToNewParent(body);
 }
예제 #60
0
        /// <summary>
        /// Determines if <paramref name="header"/>, <paramref name="latchingNode"/> and <paramref name="nodesInLoop"/> can form a loop.
        /// </summary>
        /// <param name="header">The header of the loop.</param>
        /// <param name="latchingNode">The latching node of the loop.</param>
        /// <param name="nodesInLoop">The body of the loop.</param>
        /// <returns>Returns true, if correct loop can be formed.</returns>
		private bool CanBeLoop(ILogicalConstruct header, ILogicalConstruct latchingNode, ICollection<DFSTNode> nodesInLoop)
		{
			if (header == null || latchingNode == null)
			{
				return false;
			}

			ICollection<ILogicalConstruct> constructsInLoop = GetConstructsCollection(nodesInLoop);

			foreach (ILogicalConstruct node in constructsInLoop)
			{
				if (!CanBeInLoop(node, constructsInLoop, header))
				{
					return false;
				}
			}
			return true;
		}