public void ExplodedGraph_BothBranchesVisited_NonCondition()
        {
            string        testInput = "var str = this?.ToString();";
            SemanticModel semanticModel;
            var           method       = ControlFlowGraphTest.Compile(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var countConditionEvaluated = 0;

            explodedGraph.ConditionEvaluated += (sender, args) => { countConditionEvaluated++; };

            var visitedBlocks = new HashSet <Block>();

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                visitedBlocks.Add(args.ProgramPoint.Block);
            };

            explodedGraph.Walk();

            Assert.IsTrue(explorationEnded);
            Assert.AreEqual(cfg.Blocks.Count() - 1 /* Exit block */, visitedBlocks.Count);
            Assert.AreEqual(0, countConditionEvaluated);
        }
Exemple #2
0
        public static ControlFlowGraph LiveVariableDeleteDeadCode(ControlFlowGraph cfg)
        {
            var newInstructions = new List <Instruction>();

            var activeVariable    = new LiveVariableAnalysis();
            var resActiveVariable = activeVariable.Execute(cfg);

            foreach (var x in cfg.GetCurrentBasicBlocks().Take(cfg.GetCurrentBasicBlocks().Count - 1).Skip(1))
            {
                var instructionsTemp = x.GetInstructions();
                if (resActiveVariable.ContainsKey(x))
                {
                    var InOutTemp = resActiveVariable[x];
                    foreach (var i in instructionsTemp)
                    {
                        if (!InOutTemp.Out.Contains(i.Result) && i.Operation == "assign" && i.Argument1 != i.Result)
                        {
                            if (i.Label != "")
                            {
                                newInstructions.Add(new Instruction(i.Label, "noop", "", "", ""));
                            }
                        }
                        else
                        {
                            newInstructions.Add(i);
                        }
                    }
                }
            }
            return(new ControlFlowGraph(newInstructions));
        }
Exemple #3
0
        public void LiveVariableTest()
        {
            var program   = @"
var a,b,c,i;

for i = 1,b {
	input (a);
	c = c + a;
	print(c);
	if c < b
		c = c + 1;
	else {
		b = b - 1;
		print(b);
		print(c);
	}
}

print (c+a+b);";
            var graph     = GenCFG(program);
            var algorithm = new LiveVariableAnalysis();

            algorithm.Execute(graph);
            var iterationsFast = algorithm.Iterations;

            algorithm.Execute(graph, false);
            var iterationsSlow = algorithm.Iterations;

            Assert.LessOrEqual(iterationsFast, iterationsSlow);
        }
        public void ExplodedGraph_LoopExploration()
        {
            string        testInput = "var i = 0; while (i < 1) { i = i + 1; }";
            SemanticModel semanticModel;
            var           method       = ControlFlowGraphTest.Compile(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var exceeded = 0;

            explodedGraph.ProgramPointVisitCountExceedLimit += (sender, args) =>
            {
                exceeded++;
                args.ProgramPoint.Block.Instructions.Where(i => i.ToString() == "i < 1").Should().NotBeEmpty();
            };

            explodedGraph.Walk();

            Assert.IsTrue(explorationEnded);
            Assert.AreEqual(1, exceeded);
        }
            private void ProcessIdentifier(SyntaxNode instruction, HashSet <SyntaxNode> assignmentLhs, HashSet <ISymbol> liveOut)
            {
                var identifier = (IdentifierNameSyntax)instruction;
                var symbol     = context.SemanticModel.GetSymbolInfo(identifier).Symbol;

                if (!IsSymbolRelevant(symbol))
                {
                    return;
                }

                if (!identifier.GetSelfOrTopParenthesizedExpression().IsInNameofCall(context.SemanticModel) &&
                    LiveVariableAnalysis.IsLocalScoped(symbol, declaration))
                {
                    if (LiveVariableAnalysis.IsOutArgument(identifier))
                    {
                        liveOut.Remove(symbol);
                    }
                    else
                    {
                        if (!assignmentLhs.Contains(identifier))
                        {
                            liveOut.Add(symbol);
                        }
                    }
                }
            }
        public static (bool wasChanged, List <Instruction> instructions) LiveVariableDeleteDeadCode(List <Instruction> instructions)
        {
            var wasChanged        = false;
            var newInstructions   = new List <Instruction>();
            var divResult         = BasicBlockLeader.DivideLeaderToLeader(newInstructions);
            var cfg               = new ControlFlowGraph(divResult);
            var activeVariable    = new LiveVariableAnalysis();
            var resActiveVariable = activeVariable.Execute(cfg);

            newInstructions = instructions.GetRange(0, instructions.Count - 1);
            foreach (var x in resActiveVariable)
            {
                foreach (var y in x.Value.Out)
                {
                    if (instructions[instructions.Count - 1].Result != y && instructions[instructions.Count - 1].Operation == "assign" && instructions[instructions.Count - 1].Argument1 != y)
                    {
                        wasChanged = true;
                    }
                    else
                    {
                        return(wasChanged, newInstructions);
                    }
                }
            }
            newInstructions.Add(instructions[instructions.Count - 1]);
            return(wasChanged, newInstructions);
        }
Exemple #7
0
        public void ReachingDefinitionsTest()
        {
            var program   = @"
var i, m, j, n, a, u1, u2, u3, k;
1: i = m - 1;
2: j = n;
3: a = u1;

for k = 0, 1
{
    i = i + 1;
    j = j - 1;

    if i < j
        a = u2;
    i = u3;
}";
            var graph     = GenCFG(program);
            var algorithm = new LiveVariableAnalysis();

            algorithm.Execute(graph);
            var iterationsFast = algorithm.Iterations;

            algorithm.Execute(graph, false);
            var iterationsSlow = algorithm.Iterations;

            Assert.LessOrEqual(iterationsFast, iterationsSlow);
        }
        public void ExplodedGraph_SequentialInput_Max()
        {
            var inputBuilder = new StringBuilder();

            for (int i = 0; i < ExplodedGraph.MaxStepCount / 2 + 1; i++)
            {
                inputBuilder.AppendLine($"var x{i} = true;");
            }
            string        testInput = inputBuilder.ToString();
            SemanticModel semanticModel;
            var           method       = ControlFlowGraphTest.Compile(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };
            var maxStepCountReached = false;

            explodedGraph.MaxStepCountReached += (sender, args) => { maxStepCountReached = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            explodedGraph.Walk();

            Assert.IsFalse(explorationEnded);
            Assert.IsTrue(maxStepCountReached);
            Assert.AreEqual(0, numberOfExitBlockReached);
        }
Exemple #9
0
        public static (bool wasChanged, IReadOnlyList <Instruction> instructions) LiveVariableDeleteDeadCode(IReadOnlyList <Instruction> instructions)
        {
            var wasChanged        = false;
            var newInstructions   = new List <Instruction>();
            var divResult         = BasicBlockLeader.DivideLeaderToLeader(instructions);
            var cfg               = new ControlFlowGraph(divResult);
            var activeVariable    = new LiveVariableAnalysis();
            var resActiveVariable = activeVariable.Execute(cfg);

            foreach (var x in divResult)
            {
                var instructionsTemp = x.GetInstructions();
                if (resActiveVariable.ContainsKey(x))
                {
                    var InOutTemp = resActiveVariable[x];
                    foreach (var i in instructionsTemp)
                    {
                        if (!InOutTemp.Out.Contains(i.Result) && i.Operation == "assign" && i.Argument1 != i.Result)
                        {
                            wasChanged = true;
                            if (i.Label != "")
                            {
                                newInstructions.Add(new Instruction(i.Label, "noop", "", "", ""));
                            }
                        }
                        else
                        {
                            newInstructions.Add(i);
                        }
                    }
                }
            }
            return(wasChanged, newInstructions);
        }
        public void ExplodedGraph_SingleBranchVisited_If()
        {
            string        testInput = "var a = false; bool b; if (a) { b = true; } else { b = false; } a = b;";
            SemanticModel semanticModel;
            var           method         = ControlFlowGraphTest.Compile(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol   = semanticModel.GetDeclaredSymbol(method);
            var           varDeclarators = method.DescendantNodes().OfType <VariableDeclaratorSyntax>();
            var           aSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "a"));
            var           bSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "b"));

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfLastInstructionVisits = 0;
            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "a = false")
                {
                    Assert.IsTrue(args.ProgramState.GetSymbolValue(aSymbol) == SymbolicValue.False);
                }
                if (args.Instruction.ToString() == "b = true")
                {
                    Assert.Fail("We should never get into this branch");
                }
                if (args.Instruction.ToString() == "b = false")
                {
                    Assert.IsTrue(args.ProgramState.GetSymbolValue(bSymbol) == SymbolicValue.False);
                    Assert.IsNull(args.ProgramState.GetSymbolValue(aSymbol),
                                  "a is dead, so there should be no associated value to it.");
                }
                if (args.Instruction.ToString() == "a = b")
                {
                    numberOfLastInstructionVisits++;
                }
            };

            explodedGraph.Walk();

            Assert.IsTrue(explorationEnded);
            Assert.AreEqual(10, numberOfProcessedInstructions);
            Assert.AreEqual(1, numberOfExitBlockReached);
            Assert.AreEqual(1, numberOfLastInstructionVisits);
        }
        public void ExplodedGraph_SequentialInput()
        {
            string        testInput = "var a = true; var b = false; b = !b; a = (b);";
            SemanticModel semanticModel;
            var           method         = ControlFlowGraphTest.Compile(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol   = semanticModel.GetDeclaredSymbol(method);
            var           varDeclarators = method.DescendantNodes().OfType <VariableDeclaratorSyntax>();
            var           aSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "a"));
            var           bSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "b"));

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "a = true")
                {
                    Assert.IsTrue(args.ProgramState.GetSymbolValue(aSymbol) == SymbolicValue.True);
                }
                if (args.Instruction.ToString() == "b = false")
                {
                    Assert.IsTrue(args.ProgramState.GetSymbolValue(bSymbol) == SymbolicValue.False);
                }
                if (args.Instruction.ToString() == "b = !b")
                {
                    Assert.IsFalse(args.ProgramState.GetSymbolValue(bSymbol) == SymbolicValue.False);
                    Assert.IsFalse(args.ProgramState.GetSymbolValue(bSymbol) == SymbolicValue.True);
                }
                if (args.Instruction.ToString() == "a = (b)")
                {
                    Assert.AreEqual(
                        args.ProgramState.GetSymbolValue(bSymbol),
                        args.ProgramState.GetSymbolValue(aSymbol));
                }
            };

            explodedGraph.Walk();

            Assert.IsTrue(explorationEnded);
            Assert.AreEqual(11, numberOfProcessedInstructions);
            Assert.AreEqual(1, numberOfExitBlockReached);
        }
            private static void ReportOnAssignment(AssignmentExpressionSyntax assignment, ExpressionSyntax left, ISymbol symbol,
                                                   ISymbol declaration, HashSet <SyntaxNode> assignmentLhs, HashSet <ISymbol> outState, SyntaxNodeAnalysisContext context)
            {
                if (LiveVariableAnalysis.IsLocalScoped(symbol, declaration) &&
                    !outState.Contains(symbol))
                {
                    var location = GetFirstLineLocationFromToken(assignment.OperatorToken, assignment.Right);
                    context.ReportDiagnostic(Diagnostic.Create(rule, location, symbol.Name));
                }

                assignmentLhs.Add(left);
            }
        private List <(HashSet <string> IN, HashSet <string> OUT)> Execute(List <Instruction> TAC)
        {
            var cfg = GenCFG(TAC);

            var liveAct = new LiveVariableAnalysis();

            liveAct.ExecuteInternal(cfg);

            var listAct = liveAct.dictInOut
                          .Select(x => x.Value)
                          .Select(y => (y.IN as HashSet <string>, y.OUT as HashSet <string>));

            return(listAct.ToList());
        }
Exemple #14
0
        private List <(HashSet <string> IN, HashSet <string> OUT)> Execute(List <Instruction> TAC)
        {
            var blocks = BasicBlockLeader.DivideLeaderToLeader(TAC);
            var cfg    = new ControlFlowGraph(blocks);

            var liveAct = new LiveVariableAnalysis();

            liveAct.ExecuteInternal(cfg);

            var listAct = liveAct.dictInOut
                          .Select(x => x.Value)
                          .Select(y => (y.IN as HashSet <string>, y.OUT as HashSet <string>));

            return(listAct.ToList());
        }
        private static void CheckForDeadStores(CSharpSyntaxNode node, ISymbol declaration, SyntaxNodeAnalysisContext context)
        {
            IControlFlowGraph cfg;

            if (!ControlFlowGraph.TryGet(node, context.SemanticModel, out cfg))
            {
                return;
            }

            var lva = LiveVariableAnalysis.Analyze(cfg, declaration, context.SemanticModel);

            foreach (var block in cfg.Blocks)
            {
                CheckCfgBlockForDeadStores(block, lva.GetLiveOut(block), lva.CapturedVariables, node, declaration, context);
            }
        }
        public void ExplodedGraph_AllBranchesVisited()
        {
            string        testInput = "int i = 1; switch (i) { case 1: default: cw1(); break; case 2: cw2(); break; }";
            SemanticModel semanticModel;
            var           method       = ControlFlowGraphTest.Compile(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfCw1InstructionVisits  = 0;
            var numberOfCw2InstructionVisits  = 0;
            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "cw1()")
                {
                    numberOfCw1InstructionVisits++;
                }
                if (args.Instruction.ToString() == "cw2()")
                {
                    numberOfCw2InstructionVisits++;
                }
            };

            explodedGraph.Walk();

            Assert.IsTrue(explorationEnded);
            Assert.AreEqual(1, numberOfExitBlockReached);
            Assert.AreEqual(1, numberOfCw1InstructionVisits);
            Assert.AreEqual(1, numberOfCw2InstructionVisits);
        }
        public void ExplodedGraph_SingleBranchVisited_And()
        {
            string        testInput = "var a = false; if (a && !a) { a = true; }";
            SemanticModel semanticModel;
            var           method         = ControlFlowGraphTest.Compile(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol   = semanticModel.GetDeclaredSymbol(method);
            var           varDeclarators = method.DescendantNodes().OfType <VariableDeclaratorSyntax>();
            var           aSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "a"));

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "a = !true")
                {
                    Assert.IsTrue(args.ProgramState.GetSymbolValue(aSymbol) == SymbolicValue.False);     // Roslyn is clever !true has const value.
                }
                if (args.Instruction.ToString() == "!a")
                {
                    Assert.Fail("We should never get into this branch");
                }
            };

            explodedGraph.Walk();

            Assert.IsTrue(explorationEnded);
            Assert.AreEqual(1, numberOfExitBlockReached);
        }
            private void ProcessPostfixExpression(SyntaxNode instruction, HashSet <ISymbol> liveOut)
            {
                var postfixExpression = (PostfixUnaryExpressionSyntax)instruction;
                var operand           = postfixExpression.Operand.RemoveParentheses();

                if (operand.IsKind(SyntaxKind.IdentifierName))
                {
                    var symbol = context.SemanticModel.GetSymbolInfo(operand).Symbol;
                    if (!IsSymbolRelevant(symbol))
                    {
                        return;
                    }

                    if (LiveVariableAnalysis.IsLocalScoped(symbol, declaration) &&
                        !liveOut.Contains(symbol))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(rule, postfixExpression.GetLocation(), symbol.Name));
                    }
                }
            }
        public void ExplodedGraph_NonLocalSymbolBranching()
        {
            string        testInput = "if (field) { cw(); }";
            SemanticModel semanticModel;
            var           method       = ControlFlowGraphTest.Compile(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol = semanticModel.GetDeclaredSymbol(method);
            var           fieldSymbol  = semanticModel.GetSymbolInfo(
                method.DescendantNodes().OfType <IdentifierNameSyntax>().First(d => d.Identifier.ToString() == "field")).Symbol;

            Assert.IsNotNull(fieldSymbol);

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfProcessedInstructions = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "field")
                {
                    Assert.IsNull(args.ProgramState.GetSymbolValue(fieldSymbol));
                }
            };

            explodedGraph.Walk();

            Assert.IsTrue(explorationEnded);
            Assert.AreEqual(1, numberOfExitBlockReached);
        }
Exemple #20
0
        private static void ReportOnDeadParametersAtEntry(BaseMethodDeclarationSyntax declaration, IMethodSymbol methodSymbol,
                                                          IImmutableList <IParameterSymbol> noReportOnParameters, SyntaxNodeAnalysisContext context)
        {
            if (!declaration.IsKind(SyntaxKind.MethodDeclaration) ||
                declaration.Body == null)
            {
                return;
            }

            var excludedParameters = noReportOnParameters;

            if (methodSymbol.IsExtensionMethod)
            {
                excludedParameters = excludedParameters.Add(methodSymbol.Parameters.First());
            }

            excludedParameters = excludedParameters.AddRange(methodSymbol.Parameters.Where(p => p.RefKind != RefKind.None));

            var candidateParameters = methodSymbol.Parameters.Except(excludedParameters);

            if (!candidateParameters.Any())
            {
                return;
            }

            IControlFlowGraph cfg;

            if (!ControlFlowGraph.TryGet(declaration.Body, context.SemanticModel, out cfg))
            {
                return;
            }

            var lva            = LiveVariableAnalysis.Analyze(cfg, methodSymbol, context.SemanticModel);
            var liveParameters = lva.GetLiveIn(cfg.EntryBlock).OfType <IParameterSymbol>();

            ReportOnUnusedParameters(declaration, candidateParameters.Except(liveParameters).Except(lva.CapturedVariables), MessageDead,
                                     context, isRemovable: false);
        }
Exemple #21
0
        public void LiveVariableIterativeTest()
        {
            var program = @"
var a,b,c;

input (b);
a = b + 1;
if a < c
	c = b - a;
else
	c = b + a;
print (c);"
            ;

            var cfg = GenCFG(program);
            var resActiveVariable = new LiveVariableAnalysis().Execute(cfg);
            var actual            = cfg.GetCurrentBasicBlocks()
                                    .Select(z => resActiveVariable[z])
                                    .Select(p => ((IEnumerable <string>)p.In, (IEnumerable <string>)p.Out))
                                    .ToList();

            var expected =
                new List <(IEnumerable <string>, IEnumerable <string>)>()
            {
                (new HashSet <string>()
                {
                    "c"
                }, new HashSet <string>()
                {
                    "c"
                }),
                (new HashSet <string>()
                {
                    "c"
                }, new HashSet <string>()
                {
                    "a", "b"
                }),
                (new HashSet <string>()
                {
                    "a", "b"
                }, new HashSet <string>()
                {
                    "c"
                }),
                (new HashSet <string>()
                {
                    "a", "b"
                }, new HashSet <string>()
                {
                    "c"
                }),
                (new HashSet <string>()
                {
                    "c"
                }, new HashSet <string>()
                {
                }),
                (new HashSet <string>()
                {
                }, new HashSet <string>()
                {
                })
            };

            AssertSet(expected, actual);
        }
Exemple #22
0
        public void LiveVariableIterativeTest()
        {
            var TAC = GenTAC(@"
var a,b,c;

input (b);
a = b + 1;
if a < c
	c = b - a;
else
	c = b + a;
print (c);"
                             );

            var cfg               = new ControlFlowGraph(BasicBlockLeader.DivideLeaderToLeader(TAC));
            var activeVariable    = new LiveVariableAnalysis();
            var resActiveVariable = activeVariable.Execute(cfg);
            var In     = new HashSet <string>();
            var Out    = new HashSet <string>();
            var actual = new List <(HashSet <string> IN, HashSet <string> OUT)>();

            foreach (var x in cfg.GetCurrentBasicBlocks().Select(z => resActiveVariable[z]))
            {
                foreach (var y in x.In)
                {
                    In.Add(y);
                }

                foreach (var y in x.Out)
                {
                    Out.Add(y);
                }
                actual.Add((new HashSet <string>(In), new HashSet <string>(Out)));
                In.Clear(); Out.Clear();
            }

            var expected =
                new List <(HashSet <string> IN, HashSet <string> OUT)>()
            {
                (new HashSet <string>()
                {
                    "c"
                }, new HashSet <string>()
                {
                    "c"
                }),
                (new HashSet <string>()
                {
                    "c"
                }, new HashSet <string>()
                {
                    "a", "b"
                }),
                (new HashSet <string>()
                {
                    "a", "b"
                }, new HashSet <string>()
                {
                    "c"
                }),
                (new HashSet <string>()
                {
                    "a", "b"
                }, new HashSet <string>()
                {
                    "c"
                }),
                (new HashSet <string>()
                {
                    "c"
                }, new HashSet <string>()
                {
                }),
                (new HashSet <string>()
                {
                }, new HashSet <string>()
                {
                })
            };

            AssertSet(expected, actual);
        }
        public void ExplodedGraph_NonDecisionMakingAssignments()
        {
            string        testInput = "var a = true; a |= false; var b = 42; b++; ++b;";
            SemanticModel semanticModel;
            var           method         = ControlFlowGraphTest.Compile(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol   = semanticModel.GetDeclaredSymbol(method);
            var           varDeclarators = method.DescendantNodes().OfType <VariableDeclaratorSyntax>();
            var           aSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "a"));
            var           bSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "b"));

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);

            SymbolicValue sv = null;
            var           numberOfProcessedInstructions = 0;
            var           branchesVisited = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "a = true")
                {
                    branchesVisited++;
                    Assert.IsTrue(args.ProgramState.GetSymbolValue(aSymbol) == SymbolicValue.True);
                }
                if (args.Instruction.ToString() == "a |= false")
                {
                    branchesVisited++;
                    Assert.IsNotNull(args.ProgramState.GetSymbolValue(aSymbol));
                    Assert.IsFalse(args.ProgramState.GetSymbolValue(aSymbol) == SymbolicValue.False);
                    Assert.IsFalse(args.ProgramState.GetSymbolValue(aSymbol) == SymbolicValue.True);
                }
                if (args.Instruction.ToString() == "b = 42")
                {
                    branchesVisited++;
                    sv = args.ProgramState.GetSymbolValue(bSymbol);
                    Assert.IsNotNull(sv);
                }
                if (args.Instruction.ToString() == "b++")
                {
                    branchesVisited++;
                    var svNew = args.ProgramState.GetSymbolValue(bSymbol);
                    Assert.IsNotNull(svNew);
                    Assert.AreNotEqual(sv, svNew);
                }
                if (args.Instruction.ToString() == "++b")
                {
                    branchesVisited++;
                    var svNew = args.ProgramState.GetSymbolValue(bSymbol);
                    Assert.IsNotNull(svNew);
                    Assert.AreNotEqual(sv, svNew);
                }
            };

            explodedGraph.Walk();

            Assert.AreEqual(11, numberOfProcessedInstructions);
            Assert.AreEqual(5, branchesVisited);
        }
 public static Common.LiveVariableAnalysis Analyze(IControlFlowGraph controlFlowGraph, ISymbol declaration, SemanticModel semanticModel)
 {
     var lva = new LiveVariableAnalysis(controlFlowGraph, declaration, semanticModel);
     lva.PerformAnalysis();
     return lva;
 }
        public void ExplodedGraph_BothBranchesVisited()
        {
            string        testInput = "var a = false; bool b; if (inParameter) { b = inParameter; } else { b = !inParameter; } a = b;";
            SemanticModel semanticModel;
            var           method       = ControlFlowGraphTest.Compile(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var varDeclarators = method.DescendantNodes().OfType <VariableDeclaratorSyntax>();
            var aSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "a"));
            var bSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "b"));

            var parameters        = method.DescendantNodes().OfType <ParameterSyntax>();
            var inParameterSymbol = semanticModel.GetDeclaredSymbol(parameters.First(d => d.Identifier.ToString() == "inParameter"));

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfLastInstructionVisits = 0;
            var numberOfProcessedInstructions = 0;

            var visitedBlocks   = new HashSet <Block>();
            var branchesVisited = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                visitedBlocks.Add(args.ProgramPoint.Block);

                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "a = false")
                {
                    branchesVisited++;

                    Assert.IsTrue(args.ProgramState.GetSymbolValue(aSymbol) == SymbolicValue.False);     // Roslyn is clever !true has const value.
                }
                if (args.Instruction.ToString() == "b = inParameter")
                {
                    branchesVisited++;

                    Assert.IsTrue(bSymbol.HasConstraint(BoolConstraint.True, args.ProgramState));
                    Assert.IsTrue(inParameterSymbol.HasConstraint(BoolConstraint.True, args.ProgramState));
                }
                if (args.Instruction.ToString() == "b = !inParameter")
                {
                    branchesVisited++;

                    // b has value, but not true or false
                    Assert.IsNotNull(args.ProgramState.GetSymbolValue(bSymbol));
                    Assert.IsFalse(bSymbol.HasConstraint(BoolConstraint.False, args.ProgramState));
                    Assert.IsFalse(bSymbol.HasConstraint(BoolConstraint.True, args.ProgramState));

                    Assert.IsTrue(inParameterSymbol.HasConstraint(BoolConstraint.False, args.ProgramState));
                }
                if (args.Instruction.ToString() == "a = b")
                {
                    branchesVisited++;

                    Assert.IsNull(args.ProgramState.GetSymbolValue(inParameterSymbol));     // not out/ref parameter and LVA says dead
                    numberOfLastInstructionVisits++;
                }
            };

            explodedGraph.Walk();

            Assert.IsTrue(explorationEnded);
            Assert.AreEqual(4 + 1, branchesVisited);
            Assert.AreEqual(1, numberOfExitBlockReached,
                            "All variables are dead at the ExitBlock, so whenever we get there, the ExplodedGraph nodes should be the same, " +
                            "and thus should be processed only once.");
            Assert.AreEqual(2, numberOfLastInstructionVisits);

            Assert.AreEqual(cfg.Blocks.Count() - 1 /* Exit block */, visitedBlocks.Count);
        }
Exemple #26
0
        public static void Main()
        {
            var FileName = @"../../a.txt";

            try
            {
                var Text = File.ReadAllText(FileName);

                var scanner = new Scanner();
                scanner.SetSource(Text, 0);

                var parser = new Parser(scanner);

                var b = parser.Parse();
                if (!b)
                {
                    Console.WriteLine("Error");
                }
                else
                {
                    Console.WriteLine("Syntax tree built");

                    var fillParents = new FillParentsVisitor();
                    parser.root.Visit(fillParents);

                    var pp = new PrettyPrintVisitor();
                    parser.root.Visit(pp);
                    Console.WriteLine(pp.Text);

                    ASTOptimizer.Optimize(parser);
                    Console.WriteLine("\n\nAfter AST optimizations");
                    pp = new PrettyPrintVisitor();
                    parser.root.Visit(pp);
                    Console.WriteLine(pp.Text);

                    Console.WriteLine("\n\nThree address code");
                    var threeAddrCodeVisitor = new ThreeAddrGenVisitor();
                    parser.root.Visit(threeAddrCodeVisitor);
                    var threeAddressCode = threeAddrCodeVisitor.Instructions;
                    foreach (var instruction in threeAddressCode)
                    {
                        Console.WriteLine(instruction);
                    }

                    Console.WriteLine("\n\nOptimized three address code");
                    var optResult = ThreeAddressCodeOptimizer.OptimizeAll(threeAddressCode);
                    foreach (var x in optResult)
                    {
                        Console.WriteLine(x);
                    }

                    Console.WriteLine("\n\nDivided three address code");
                    var divResult = BasicBlockLeader.DivideLeaderToLeader(optResult);


                    foreach (var x in divResult)
                    {
                        foreach (var y in x.GetInstructions())
                        {
                            Console.WriteLine(y);
                        }
                        Console.WriteLine("--------------");
                    }

                    var cfg = new ControlFlowGraph(divResult);

                    Console.WriteLine("\n\n Edge Classification");
                    Console.WriteLine("----------");

                    foreach (var pair in cfg.ClassifiedEdges)
                    {
                        Console.WriteLine(pair);
                    }

                    Console.WriteLine("----------");


                    foreach (var block in cfg.GetCurrentBasicBlocks())
                    {
                        Console.WriteLine($"{cfg.VertexOf(block)}  {block.GetInstructions().First()}");
                        var children    = cfg.GetChildrenBasicBlocks(cfg.VertexOf(block));
                        var childrenStr = string.Join(" | ", children.Select(v => v.block.GetInstructions().First().ToString()));
                        Console.WriteLine($" children: {childrenStr}");

                        var parents    = cfg.GetParentsBasicBlocks(cfg.VertexOf(block));
                        var parentsStr = string.Join(" | ", parents.Select(v => v.block.GetInstructions().First().ToString()));
                        Console.WriteLine($" parents: {parentsStr}");
                    }

                    ///
                    /// LiveVariableAnalysisAlgorithm
                    ///
                    Console.WriteLine("------------");
                    Console.WriteLine();
                    var activeVariable    = new LiveVariableAnalysis();
                    var resActiveVariable = activeVariable.Execute(cfg);

                    foreach (var x in resActiveVariable)
                    {
                        foreach (var y in x.Value.In)
                        {
                            Console.WriteLine("In " + y);
                        }
                        Console.WriteLine();
                        foreach (var y in x.Value.Out)
                        {
                            Console.WriteLine("Out " + y);
                        }
                    }


                    Console.WriteLine();
                    Console.WriteLine();
                    Console.WriteLine("NatLoop");
                    var natLoops = NaturalLoop.GetAllNaturalLoops(cfg);
                    foreach (var x in natLoops)
                    {
                        if (x.Count == 0)
                        {
                            continue;
                        }
                        //Console.WriteLine("Loop");
                        for (var i = 0; i < x.Count; i++)
                        {
                            Console.WriteLine("NumberBlock:" + i);
                            foreach (var xfrom in x[i].GetInstructions())
                            {
                                Console.WriteLine(xfrom.ToString());
                            }
                        }
                        Console.WriteLine();
                        Console.WriteLine("-------------");
                    }

                    Console.WriteLine(" \nDone");
                }
            }
            catch (FileNotFoundException)
            {
                Console.WriteLine("File {0} not found", FileName);
            }
            catch (LexException e)
            {
                Console.WriteLine("Lex Error. " + e.Message);
            }
            catch (SyntaxException e)
            {
                Console.WriteLine("Syntax Error. " + e.Message);
            }
            Console.ReadLine();
        }