Пример #1
0
 private void TraverseAndBuildTree()
 {
     this.theTree = new DFSTree(this.constructToNodeMap);
     this.DFSBuild(this.constructToNodeMap.get_Item(this.entry));
     this.theTree.get_ReversePostOrder().Reverse();
     this.theTree.get_ReversePostOrder().TrimExcess();
     this.AssignOrderIndices();
     return;
 }
Пример #2
0
        /// <summary>
        /// Builds the tree starting from the graph's entry.
        /// </summary>
        private void TraverseAndBuildTree()
        {
            theTree = new DFSTree(constructToNodeMap);

            DFSTNode root = constructToNodeMap[this.entry];

            DFSBuild(root);

            //Since the nodes were added in postorder we must reverse them to get ... the reverse postorder.
            theTree.ReversePostOrder.Reverse();
            theTree.ReversePostOrder.TrimExcess();

            AssignOrderIndices();
        }
Пример #3
0
        /// <summary>
        /// Builds the tree starting from the graph's entry.
        /// </summary>
        private void TraverseAndBuildTree()
        {
            theTree = new DFSTree(constructToNodeMap);

            DFSTNode root = constructToNodeMap[this.entry];

            DFSBuild(root);

            //Since the nodes were added in postorder we must reverse them to get ... the reverse postorder.
            theTree.ReversePostOrder.Reverse();
            theTree.ReversePostOrder.TrimExcess();

            AssignOrderIndices();
        }
        /// <summary>
        /// Gets the candidates to become conditions of if constructs in postorder.
        /// </summary>
        /// <param name="construct"></param>
        /// <returns></returns>
        private IEnumerable<ConditionLogicalConstruct> GetPostOrderedIfConditionCandidates(DFSTree dfsTree)
        {
            //The post order is so that we start making the if constructs from the innermost nested first (if there is nesting).

            for (int i = dfsTree.ReversePostOrder.Count - 1; i >= 0; i--)
            {
                ConditionLogicalConstruct currentConstruct = dfsTree.ReversePostOrder[i].Construct as ConditionLogicalConstruct;

                //For candidates we take these conditions that have 2 same parent successors.
                //TODO: consider taking the conditions with 1 same parent successor.
                if (currentConstruct != null && currentConstruct.SameParentSuccessors.Count == 2)
                {
                    yield return currentConstruct;
                }
            }
        }
Пример #5
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;
        }
Пример #6
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;
		}
        /// <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;
		}
        /// <summary>
        /// Checks if the specified condition successor can be successor of the if construct.
        /// </summary>
        /// <param name="condition">The condition.</param>
        /// <param name="conditionSuccessor">The condition successor.</param>
        /// <param name="otherSuccessorFrontier">The dominance frontier of the other successor.</param>
        /// <returns>On success - the successor. Otherwise null.</returns>
        private ILogicalConstruct CheckSuccessor(ILogicalConstruct condition, ILogicalConstruct conditionSuccessor,
            HashSet<ISingleEntrySubGraph> otherSuccessorFrontier, DFSTree dfsTree)
        {
            //In order the condition successor to be successor of the if, it has to be in the dominance frontier of the other successor.
            //Also the edge between the condition and the successor should not be backedge or crossedge.
            DFSTNode successorNode;
            if(otherSuccessorFrontier.Contains(conditionSuccessor) &&
                (!dfsTree.ConstructToNodeMap.TryGetValue(conditionSuccessor, out successorNode) || dfsTree.ConstructToNodeMap[condition].CompareTo(successorNode) < 0))
            {
                return conditionSuccessor;
            }

            return null;
        }
        /// <summary>
        /// Gets an array containing the tree, forward and cross edges of the given DFS traversal tree.
        /// </summary>
        /// <param name="dfsTree">The DFS traversal tree.</param>
        /// <returns></returns>
        private DFSTEdge[] GetForwardFlowEdges(DFSTree dfsTree)
        {
            DFSTEdge[] regularEdges = new DFSTEdge[dfsTree.TreeEdges.Count + dfsTree.ForwardEdges.Count + dfsTree.CrossEdges.Count];

            int index = 0;
            FillEdgesArray(regularEdges, dfsTree.TreeEdges, ref index);
            FillEdgesArray(regularEdges, dfsTree.ForwardEdges, ref index);
            FillEdgesArray(regularEdges, dfsTree.CrossEdges, ref index);
            return regularEdges;
        }
        /// <summary>
        /// Builds the adjacency matrix of the subgraph by using the given <paramref name="dfsTree"/>.
        /// </summary>
        /// <remarks>
        /// The back edges are not included in the built subgraph.
        /// </remarks>
        /// <param name="dfsTree"></param>
        private void BuildAdjacencyMatrix(DFSTree dfsTree)
        {
            DFSTEdge[] edgeArray = GetForwardFlowEdges(dfsTree);
            adjacencyMatrix = new int[orderedVertexArray.Length, orderedVertexArray.Length];
            
            foreach (DFSTEdge edge in edgeArray)
            {
                int startIndex = edge.Start.ReversePostOrderIndex;
                int endIndex = edge.End.ReversePostOrderIndex;

                if(startIndex == endIndex)
                {
                    continue;
                }

                int weight = GetWeight(edge.Start.Construct as ILogicalConstruct, edge.End.Construct as ILogicalConstruct);
                adjacencyMatrix[startIndex, endIndex] = weight;
            }
        }