private ConditionLogicalConstruct CreateComplexCondition(ConditionLogicalConstruct conditionNode)
 {
     V_0       = conditionNode.get_ConditionExpression();
     V_1       = new HashSet <ILogicalConstruct>();
     V_2       = conditionNode;
     dummyVar0 = V_1.Add(V_2);
     V_3       = V_2.get_TrueSuccessor();
     V_4       = V_2.get_FalseSuccessor();
     while (true)
     {
         if (!this.CanBePartOfComplexCondition(V_3, V_1, V_2.get_FalseCFGSuccessor()))
         {
             if (!this.CanBePartOfComplexCondition(V_4, V_1, V_2.get_TrueCFGSuccessor()))
             {
                 break;
             }
             V_6 = V_4 as ConditionLogicalConstruct;
             if (V_6.get_TrueSuccessor() != V_3)
             {
                 V_6.Negate(this.typeSystem);
             }
             V_8 = 11;
         }
         else
         {
             V_6 = V_3 as ConditionLogicalConstruct;
             if (V_6.get_FalseSuccessor() != V_4)
             {
                 V_6.Negate(this.typeSystem);
             }
             V_8 = 12;
         }
         V_0 = new BinaryExpression(V_8, V_0, V_6.get_ConditionExpression(), this.typeSystem, null, false);
         V_0.set_ExpressionType(this.booleanTypeReference);
         V_2       = V_6;
         V_3       = V_2.get_TrueSuccessor();
         V_4       = V_2.get_FalseSuccessor();
         dummyVar1 = V_1.Add(V_2);
     }
     if (V_1.get_Count() == 1)
     {
         return(conditionNode);
     }
     V_5 = new HashSet <ConditionLogicalConstruct>();
     V_9 = V_1.GetEnumerator();
     try
     {
         while (V_9.MoveNext())
         {
             V_10      = (ConditionLogicalConstruct)V_9.get_Current();
             dummyVar2 = V_5.Add(V_10);
         }
     }
     finally
     {
         ((IDisposable)V_9).Dispose();
     }
     return(new ConditionLogicalConstruct(conditionNode, V_2, V_5, V_0));
 }
        private IfLogicalConstruct(ConditionLogicalConstruct condition, BlockLogicalConstruct thenBlock, BlockLogicalConstruct elseBlock)
        {
			condition.LogicalContainer = this;

            this.Condition = condition;
            this.Then = thenBlock;
            this.Else = elseBlock;

            RedirectChildrenToNewParent(GetIfBody());
        }
        private IfLogicalConstruct(ConditionLogicalConstruct condition, BlockLogicalConstruct thenBlock, BlockLogicalConstruct elseBlock)
        {
            condition.LogicalContainer = this;

            this.Condition = condition;
            this.Then      = thenBlock;
            this.Else      = elseBlock;

            RedirectChildrenToNewParent(GetIfBody());
        }
示例#4
0
 private IfLogicalConstruct(ConditionLogicalConstruct condition, BlockLogicalConstruct thenBlock, BlockLogicalConstruct elseBlock)
 {
     base();
     condition.set_LogicalContainer(this);
     this.set_Condition(condition);
     this.set_Then(thenBlock);
     this.set_Else(elseBlock);
     this.RedirectChildrenToNewParent(this.GetIfBody());
     return;
 }
示例#5
0
 public ConditionLogicalConstruct(ConditionLogicalConstruct entry, ConditionLogicalConstruct lastNode, HashSet <ConditionLogicalConstruct> body, Expression conditionExpression)
 {
     base();
     this.set_Entry(entry.get_FirstBlock());
     this.set_TrueCFGSuccessor(lastNode.get_TrueCFGSuccessor());
     this.set_FalseCFGSuccessor(lastNode.get_FalseCFGSuccessor());
     this.set_ConditionExpression(conditionExpression);
     this.RedirectChildrenToNewParent(this.RestoreOriginalCFGNodes(body));
     this.AddTrueFalseSuccessors();
     this.set_LogicalContainer(null);
     return;
 }
        /// <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);
        }
        public ConditionLogicalConstruct(ConditionLogicalConstruct entry, ConditionLogicalConstruct lastNode, HashSet <ConditionLogicalConstruct> body,
                                         Expression conditionExpression)
        {
            Entry = entry.FirstBlock;

            TrueCFGSuccessor  = lastNode.TrueCFGSuccessor;
            FalseCFGSuccessor = lastNode.FalseCFGSuccessor;

            ConditionExpression = conditionExpression;

            RedirectChildrenToNewParent(RestoreOriginalCFGNodes(body));

            AddTrueFalseSuccessors();

            LogicalContainer = null;
        }
示例#8
0
        /// <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);
                }
            }
        }
        public ConditionLogicalConstruct(ConditionLogicalConstruct entry, ConditionLogicalConstruct lastNode, HashSet<ConditionLogicalConstruct> body,
            Expression conditionExpression)
        {
            Entry = entry.FirstBlock;

            TrueCFGSuccessor = lastNode.TrueCFGSuccessor;
            FalseCFGSuccessor = lastNode.FalseCFGSuccessor;

            ConditionExpression = conditionExpression;

            RedirectChildrenToNewParent(RestoreOriginalCFGNodes(body));

            AddTrueFalseSuccessors();

			LogicalContainer = null;
        }
 /// <summary>
 /// Creates simple conditions containing only one CFG construct (may be partial).
 /// </summary>
 private void CreateSimpleConditions()
 {
     //Since we've split the CFG constructs in the CFGBlockSplitter, we now know that if an instruction block is a condition block,
     //the last of the (partial) CFG constructs holds the condition expression.
     //The only thing left to check is if the block is not a switch block, since switch blocks are a special case and are not proccessed as
     //normal conditions.
     foreach (CFGBlockLogicalConstruct[] cfgConstructsArray in logicalBuilderContext.CFGBlockToLogicalConstructMap.Values)
     {
         CFGBlockLogicalConstruct cfgConstruct        = cfgConstructsArray[cfgConstructsArray.Length - 1];
         InstructionBlock         theInstructionBlock = cfgConstruct.TheBlock;
         if (theInstructionBlock.Successors.Length == 2 && theInstructionBlock.Successors[0] != theInstructionBlock.Successors[1] &&
             theInstructionBlock.Last.OpCode.Code != Code.Switch)
         {
             ConditionLogicalConstruct.GroupInSimpleConditionConstruct(cfgConstruct);
         }
     }
 }
        /// <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 CreateSimpleConditions()
 {
     V_0 = this.logicalBuilderContext.get_CFGBlockToLogicalConstructMap().get_Values().GetEnumerator();
     try
     {
         while (V_0.MoveNext())
         {
             stackVariable8 = V_0.get_Current();
             V_1            = stackVariable8[(int)stackVariable8.Length - 1];
             V_2            = V_1.get_TheBlock();
             if ((int)V_2.get_Successors().Length != 2 || !InstructionBlock.op_Inequality(V_2.get_Successors()[0], V_2.get_Successors()[1]) || V_2.get_Last().get_OpCode().get_Code() == 68)
             {
                 continue;
             }
             dummyVar0 = ConditionLogicalConstruct.GroupInSimpleConditionConstruct(V_1);
         }
     }
     finally
     {
         ((IDisposable)V_0).Dispose();
     }
     return;
 }
示例#13
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);
        }
示例#14
0
        /// <summary>
        /// Gets the dominated nodes of the condition successor, only if they can form a legal block for the if construct.
        /// </summary>
        /// <param name="dominatorTree"></param>
        /// <param name="conditionSuccessor"></param>
        /// <returns>On success - a set of the nodes fo the block. Otherwise it returns null.</returns>
        private HashSet <ILogicalConstruct> GetBlockBody(DominatorTree dominatorTree, ILogicalConstruct conditionSuccessor, ConditionLogicalConstruct theCondition)
        {
            if (conditionSuccessor == dominatorTree.RootConstruct) //Corner case - the successor cannot be the entry of the construct.
            {
                return(null);
            }

            HashSet <ILogicalConstruct> body = null;

            if (conditionSuccessor.AllPredecessors.Count == 1) //The condition successor must have only one predecessor - the condition.
            {
                body = new HashSet <ILogicalConstruct>();
                foreach (ILogicalConstruct node in dominatorTree.GetDominatedNodes(conditionSuccessor))
                {
                    if (node == theCondition)
                    {
                        return(null);
                    }
                    body.Add(node);
                }
            }

            return(body);
        }
示例#15
0
        private HashSet <ILogicalConstruct> GetBlockBody(DominatorTree dominatorTree, ILogicalConstruct conditionSuccessor, ConditionLogicalConstruct theCondition)
        {
            if (conditionSuccessor == dominatorTree.get_RootConstruct())
            {
                return(null);
            }
            V_0 = null;
            if (conditionSuccessor.get_AllPredecessors().get_Count() == 1)
            {
                V_0 = new HashSet <ILogicalConstruct>();
                V_1 = dominatorTree.GetDominatedNodes(conditionSuccessor).GetEnumerator();
                try
                {
                    while (V_1.MoveNext())
                    {
                        V_2 = (ILogicalConstruct)V_1.get_Current();
                        if (V_2 != theCondition)
                        {
                            dummyVar0 = V_0.Add(V_2);
                        }
                        else
                        {
                            V_3 = null;
                            goto Label1;
                        }
                    }
                    goto Label0;
                }
                finally
                {
                    ((IDisposable)V_1).Dispose();
                }
Label1:
                return(V_3);
            }
Label0:
            return(V_0);
        }
 /// <summary>
 /// Creates a new IfLogicalConstruct and adds it to the logical tree.
 /// </summary>
 /// <param name="condition">The condition of the if.</param>
 /// <param name="theThenBlock">The then block of the if.</param>
 /// <param name="theElseBlock">The else block of the if.</param>
 /// <returns>The created if construct.</returns>
 public static IfLogicalConstruct GroupInIfConstruct(ConditionLogicalConstruct condition,
                                                     BlockLogicalConstruct theThenBlock, BlockLogicalConstruct theElseBlock)
 {
     return(new IfLogicalConstruct(condition, theThenBlock, theElseBlock));
 }
        /// <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;
		}
示例#18
0
        /// <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;
                }
            }
        }
        /// <summary>
        /// Gets the dominated nodes of the condition successor, only if they can form a legal block for the if construct.
        /// </summary>
        /// <param name="dominatorTree"></param>
        /// <param name="conditionSuccessor"></param>
        /// <returns>On success - a set of the nodes fo the block. Otherwise it returns null.</returns>
        private HashSet<ILogicalConstruct> GetBlockBody(DominatorTree dominatorTree, ILogicalConstruct conditionSuccessor, ConditionLogicalConstruct theCondition)
        {
            if(conditionSuccessor == dominatorTree.RootConstruct) //Corner case - the successor cannot be the entry of the construct.
            {
                return null;
            }

            HashSet<ILogicalConstruct> body = null;
            if(conditionSuccessor.AllPredecessors.Count == 1) //The condition successor must have only one predecessor - the condition.
            {
                body = new HashSet<ILogicalConstruct>();
                foreach (ILogicalConstruct node in dominatorTree.GetDominatedNodes(conditionSuccessor))
                {
                    if (node == theCondition)
                    {
                        return null;
                    }
                    body.Add(node);
                }
            }

            return body;
        }
        /// <summary>
        /// Tries to create a new complex condition starting from the specified.
        /// </summary>
        /// <param name="conditionNode"></param>
        /// <returns></returns>
        private ConditionLogicalConstruct CreateComplexCondition(ConditionLogicalConstruct conditionNode)
        {
            //Explanation:
            //
            //       A
            //      / \
            //     B-> C   (A -> B, C; B -> C, ...; C -> ...)
            //    /
            //A and B - condition nodes, C - common successor
            //
            //This is the representation of every short-circuit boolean expression. Depending on the relation between the conditions, all possible complex
            //boolean expressions can be made. After we've made the new condition from A and B we can continue the check for this type of construction from the
            //new node.

            //So, the purpose of the implemented algorithm is to find the "chain" (directed path containing all the nodes) of all nodes that
            //can be made into a complex condition. The reason for this is to reduce the creating of new logical constructs.

            //Holds the complex condition that we have found so far.
            Expression complexExpression = conditionNode.ConditionExpression;
            //Holds all the nodes that form the complex condition.
            HashSet<ILogicalConstruct> conditionNodes = new HashSet<ILogicalConstruct>();
            //Holds the last node in the "chain", since it's successors are the successors of the complex condition.
            ConditionLogicalConstruct lastNode = conditionNode;
            conditionNodes.Add(lastNode);
            //The true successor of the complex condition.
            ILogicalConstruct trueSuccessor = lastNode.TrueSuccessor;
            //The false successor of the complex condition.
            ILogicalConstruct falseSuccessor = lastNode.FalseSuccessor;
            while(true)
            {
                ConditionLogicalConstruct newConditionNode;
                ILogicalConstruct commonSuccessor;
                BinaryOperator @operator;

                if (CanBePartOfComplexCondition(trueSuccessor, conditionNodes, lastNode.FalseCFGSuccessor))
                {
                    //If the true successor can be added, then the common successor is the false node.
                    newConditionNode = trueSuccessor as ConditionLogicalConstruct;
                    commonSuccessor = falseSuccessor;
                    
                    //This check is to ensure that the common successor is the false successor to both the nodes.
                    if (newConditionNode.FalseSuccessor != commonSuccessor)
                    {
                        newConditionNode.Negate(typeSystem);
                    }

                    //Since both of the conditions have the common successor as false successor, then the binary operation is &&.
                    @operator = BinaryOperator.LogicalAnd;
                }
                else if (CanBePartOfComplexCondition(falseSuccessor, conditionNodes, lastNode.TrueCFGSuccessor))
                {
                    //If the false successor can be added, then the common successor is the true node.
                    newConditionNode = falseSuccessor as ConditionLogicalConstruct;
                    commonSuccessor = trueSuccessor;

                    //This check is to ensure that the common successor is the true successor to both the nodes.
                    if (newConditionNode.TrueSuccessor != commonSuccessor)
                    {
                        newConditionNode.Negate(typeSystem);
                    }

                    //Since both of the conditions have the common successor as the true successor, then the binary operation is ||.
                    @operator = BinaryOperator.LogicalOr;
                }
                else
                {
                    //If we cannot add any of the successors to the condition, we finish the search.
                    break;
                }

                //Update the variables.
                complexExpression = new BinaryExpression(@operator, complexExpression, newConditionNode.ConditionExpression, typeSystem, null);
                complexExpression.ExpressionType = booleanTypeReference;

                lastNode = newConditionNode;
                trueSuccessor = lastNode.TrueSuccessor;
                falseSuccessor = lastNode.FalseSuccessor;
                conditionNodes.Add(lastNode);
            }

            //If we haven't found any other nodes, we return the original condition construct.
            if(conditionNodes.Count == 1)
            {
                return conditionNode;
            }

            //Otherwise we make the new construct and return it.
            HashSet<ConditionLogicalConstruct> complexConditionNodes = new HashSet<ConditionLogicalConstruct>();
            foreach (ConditionLogicalConstruct conditionChild in conditionNodes)
            {
                complexConditionNodes.Add(conditionChild);
            }

            return new ConditionLogicalConstruct(conditionNode, lastNode, complexConditionNodes, complexExpression);
        }
        /// <summary>
        /// Creates a new IfLogicalConstruct and adds it to the logical tree.
        /// </summary>
        /// <param name="condition">The condition of the if.</param>
        /// <param name="theThenBlock">The then block of the if.</param>
        /// <param name="theElseBlock">The else block of the if.</param>
        /// <returns>The created if construct.</returns>
		public static IfLogicalConstruct GroupInIfConstruct(ConditionLogicalConstruct condition,
            BlockLogicalConstruct theThenBlock, BlockLogicalConstruct theElseBlock)
		{
			return new IfLogicalConstruct(condition, theThenBlock, theElseBlock);
		}
示例#22
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);
 }
        /// <summary>
        /// Tries to create a new complex condition starting from the specified.
        /// </summary>
        /// <param name="conditionNode"></param>
        /// <returns></returns>
        private ConditionLogicalConstruct CreateComplexCondition(ConditionLogicalConstruct conditionNode)
        {
            //Explanation:
            //
            //       A
            //      / \
            //     B-> C   (A -> B, C; B -> C, ...; C -> ...)
            //    /
            //A and B - condition nodes, C - common successor
            //
            //This is the representation of every short-circuit boolean expression. Depending on the relation between the conditions, all possible complex
            //boolean expressions can be made. After we've made the new condition from A and B we can continue the check for this type of construction from the
            //new node.

            //So, the purpose of the implemented algorithm is to find the "chain" (directed path containing all the nodes) of all nodes that
            //can be made into a complex condition. The reason for this is to reduce the creating of new logical constructs.

            //Holds the complex condition that we have found so far.
            Expression complexExpression = conditionNode.ConditionExpression;
            //Holds all the nodes that form the complex condition.
            HashSet <ILogicalConstruct> conditionNodes = new HashSet <ILogicalConstruct>();
            //Holds the last node in the "chain", since it's successors are the successors of the complex condition.
            ConditionLogicalConstruct lastNode = conditionNode;

            conditionNodes.Add(lastNode);
            //The true successor of the complex condition.
            ILogicalConstruct trueSuccessor = lastNode.TrueSuccessor;
            //The false successor of the complex condition.
            ILogicalConstruct falseSuccessor = lastNode.FalseSuccessor;

            while (true)
            {
                ConditionLogicalConstruct newConditionNode;
                ILogicalConstruct         commonSuccessor;
                BinaryOperator            @operator;

                if (CanBePartOfComplexCondition(trueSuccessor, conditionNodes, lastNode.FalseCFGSuccessor))
                {
                    //If the true successor can be added, then the common successor is the false node.
                    newConditionNode = trueSuccessor as ConditionLogicalConstruct;
                    commonSuccessor  = falseSuccessor;

                    //This check is to ensure that the common successor is the false successor to both the nodes.
                    if (newConditionNode.FalseSuccessor != commonSuccessor)
                    {
                        newConditionNode.Negate(typeSystem);
                    }

                    //Since both of the conditions have the common successor as false successor, then the binary operation is &&.
                    @operator = BinaryOperator.LogicalAnd;
                }
                else if (CanBePartOfComplexCondition(falseSuccessor, conditionNodes, lastNode.TrueCFGSuccessor))
                {
                    //If the false successor can be added, then the common successor is the true node.
                    newConditionNode = falseSuccessor as ConditionLogicalConstruct;
                    commonSuccessor  = trueSuccessor;

                    //This check is to ensure that the common successor is the true successor to both the nodes.
                    if (newConditionNode.TrueSuccessor != commonSuccessor)
                    {
                        newConditionNode.Negate(typeSystem);
                    }

                    //Since both of the conditions have the common successor as the true successor, then the binary operation is ||.
                    @operator = BinaryOperator.LogicalOr;
                }
                else
                {
                    //If we cannot add any of the successors to the condition, we finish the search.
                    break;
                }

                //Update the variables.
                complexExpression = new BinaryExpression(@operator, complexExpression, newConditionNode.ConditionExpression, typeSystem, null);
                complexExpression.ExpressionType = booleanTypeReference;

                lastNode       = newConditionNode;
                trueSuccessor  = lastNode.TrueSuccessor;
                falseSuccessor = lastNode.FalseSuccessor;
                conditionNodes.Add(lastNode);
            }

            //If we haven't found any other nodes, we return the original condition construct.
            if (conditionNodes.Count == 1)
            {
                return(conditionNode);
            }

            //Otherwise we make the new construct and return it.
            HashSet <ConditionLogicalConstruct> complexConditionNodes = new HashSet <ConditionLogicalConstruct>();

            foreach (ConditionLogicalConstruct conditionChild in conditionNodes)
            {
                complexConditionNodes.Add(conditionChild);
            }

            return(new ConditionLogicalConstruct(conditionNode, lastNode, complexConditionNodes, complexExpression));
        }