Exemple #1
0
        /// <summary>
        /// Constructs a confrolflow graph
        /// </summary>
        /// <param name="globalCode">Ast Tree</param>
        /// <param name="file">Information about source file</param>
        private ControlFlowGraph(GlobalCode globalCode, FileInfo file)
        {
            File            = file;
            this.globalCode = globalCode;
            List <Statement> functionsAndClasses = new List <Statement>();

            foreach (var statement in globalCode.Statements)
            {
                if (statement is TypeDecl || statement is FunctionDecl)
                {
                    functionsAndClasses.Add(statement);
                }
            }

            foreach (var statement in functionsAndClasses)
            {
                globalCode.Statements.Remove(statement);
            }

            globalCode.Statements.InsertRange(0, functionsAndClasses);

            this.visitor = new CFGVisitor(this);
            globalCode.VisitMe(visitor);

            PostProcess(visitor);
        }
Exemple #2
0
 /// <summary>
 /// Function called on end of creating controlflow graph.
 /// </summary>
 /// <param name="visitor">visitor which created controlflow graph</param>
 private void PostProcess(CFGVisitor visitor)
 {
     visitor.CheckLabels();
     // TODO: simplifying control flow graph currently does not work with worklist segments (see BasicBlock.AfterWorklistSegment)
     // when CFG is simplifyed, basic blocks corresponding to ends of some segments can be removed => modify SimplifyGraph in order
     // to not remove empty basic blocks if they end worklist segemnts.
     //start.SimplifyGraph();
 }
Exemple #3
0
 /// <summary>
 /// Constructs a confrolflow graph. This method should be used only for testing with purpose of testing.
 /// </summary>
 /// <param name="globalCode">needed for drawing</param>
 /// <param name="function">function to construct controlflow graph</param>
 /// <param name="file">Information about source file</param>
 private ControlFlowGraph(GlobalCode globalCode, MethodDecl function, FileInfo file)
 {
     File            = file;
     this.globalCode = globalCode;
     this.visitor    = new CFGVisitor(this);
     start           = visitor.MakeFunctionCFG(function, function.Body);
     PostProcess(visitor);
 }
Exemple #4
0
        /// <summary>
        /// Connects TrueBranch and FalseBranch to From. TrueBranch is followed from From if the condition holds,
        /// FalseBranch is followed from From if the condition does not hold.
        ///
        /// If decompose is true, it decomposes the condition expression using logical operations with respect to
        /// shortcircuit evaluation.
        /// Note that analyzer now expects that the condition expressions are decomposed and it no longer supports
        /// condition expressions that are not decomposed.
        /// </summary>
        /// <param name="condition">the condition of the branching.</param>
        /// <param name="From">the basic block where from which the branching starts.</param>
        /// <param name="TrueBranch">the branch which is taken if the condition holds.</param>
        /// <param name="FalseBranch">the branch which is taken if the condition does not hold.</param>
        /// <param name="decompose"></param>
        internal static void ConnectConditionalBranching(Expression condition, BasicBlock From, BasicBlock TrueBranch, BasicBlock FalseBranch, bool decompose = true)
        {
            var binaryCondition = condition as BinaryEx;

            if (!decompose || binaryCondition == null || (binaryCondition.PublicOperation != Operations.And && binaryCondition.PublicOperation != Operations.Or && binaryCondition.PublicOperation != Operations.Xor))
            {
                ConditionalEdge.AddConditionalEdge(From, TrueBranch, condition);
                DirectEdge.ConnectDirectEdge(From, FalseBranch);
                return;
            }

            BasicBlock intermediateBasicBlock = null;

            switch (binaryCondition.PublicOperation)
            {
            case Operations.And:
                intermediateBasicBlock = new BasicBlock();
                ConnectConditionalBranching(binaryCondition.LeftExpr, From, intermediateBasicBlock, FalseBranch);
                From = intermediateBasicBlock;
                ConnectConditionalBranching(binaryCondition.RightExpr, From, TrueBranch, FalseBranch);
                break;

            case Operations.Or:
                intermediateBasicBlock = new BasicBlock();
                ConnectConditionalBranching(binaryCondition.LeftExpr, From, TrueBranch, intermediateBasicBlock);
                From = intermediateBasicBlock;
                ConnectConditionalBranching(binaryCondition.RightExpr, From, TrueBranch, FalseBranch);
                break;

            case Operations.Xor:
                // Expands A xor B to (A and !B) || (!A and B)

                // Expansion expands A to A and !A and B to B and !B
                // For A and !A we the AST elements cannot be shared (must be unique) - the same for B and !B
                // We thus make copies of ast elements of left and right expression and use the copies to represent !A and !B
                var leftNegation  = new UnaryEx(Operations.LogicNegation, CFGVisitor.DeepCopyAstExpressionCopyVisitor(binaryCondition.LeftExpr));
                var rightNegation = new UnaryEx(Operations.LogicNegation, CFGVisitor.DeepCopyAstExpressionCopyVisitor(binaryCondition.RightExpr));

                var leftExpression  = new BinaryEx(Operations.And, binaryCondition.LeftExpr, rightNegation);
                var rightExpression = new BinaryEx(Operations.And, leftNegation, binaryCondition.RightExpr);
                var xorExpression   = new BinaryEx(Operations.Or, leftExpression, rightExpression);
                ConnectConditionalBranching(xorExpression, From, TrueBranch, FalseBranch);

                /*
                 * // Translation of xor in the level of control flow graph. More efficient than expansion of AST (translation in the level of program code).
                 * // Does not work because AST of sharing AST elements
                 * var intermediateBasicBlock1 = new BasicBlock();
                 * var intermediateBasicBlock2 = new BasicBlock();
                 * VisitIfStmtRec(binaryCondition.LeftExpr, intermediateBasicBlock1, intermediateBasicBlock2);
                 * FromBlock = intermediateBasicBlock1;
                 * VisitIfStmtRec(binaryCondition.RightExpr, FalseSink, TrueSink);
                 * FromBlock = intermediateBasicBlock2;
                 * VisitIfStmtRec(binaryCondition.RightExpr, TrueSink, FalseSink);*/
                break;
            }
        }