Пример #1
0
 internal override void ReplaceSuccessors(Dictionary<Block, Block> replacementMapping)
 {
     if (replacementMapping.ContainsKey(SuccessorBlock))
     {
         SuccessorBlock = replacementMapping[SuccessorBlock];
     }
 }
Пример #2
0
        internal SimpleBlock(Block successor)
        {
            if (successor == null)
            {
                throw new ArgumentNullException(nameof(successor));
            }

            SuccessorBlock = successor;
        }
Пример #3
0
        internal override void ReplaceSuccessors(Dictionary<Block, Block> replacementMapping)
        {
            base.ReplaceSuccessors(replacementMapping);

            if (WouldBeSuccessor != null && replacementMapping.ContainsKey(WouldBeSuccessor))
            {
                WouldBeSuccessor = replacementMapping[WouldBeSuccessor];
            }
        }
        internal ForeachCollectionProducerBlock(ForEachStatementSyntax foreachNode, Block successor)
            : base(successor)
        {
            if (foreachNode == null)
            {
                throw new ArgumentNullException(nameof(foreachNode));
            }

            ForeachNode = foreachNode;
        }
Пример #5
0
        internal ForInitializerBlock(ForStatementSyntax forNode, Block successor)
            : base(successor)
        {
            if (forNode == null)
            {
                throw new ArgumentNullException(nameof(forNode));
            }

            ForNode = forNode;
        }
Пример #6
0
        internal JumpBlock(SyntaxNode jumpNode, Block successor, Block wouldBeSuccessor)
            : base(successor)
        {
            if (jumpNode == null)
            {
                throw new ArgumentNullException(nameof(jumpNode));
            }

            JumpNode = jumpNode;
            WouldBeSuccessor = wouldBeSuccessor;
        }
Пример #7
0
        internal BinaryBranchBlock(SyntaxNode branchingNode, Block trueSuccessor, Block falseSuccessor)
            : base(branchingNode, trueSuccessor, falseSuccessor)
        {
            if (trueSuccessor == null)
            {
                throw new ArgumentNullException(nameof(trueSuccessor));
            }

            if (falseSuccessor == null)
            {
                throw new ArgumentNullException(nameof(falseSuccessor));
            }
        }
        protected override void ProcessBlock(Block block, out HashSet<ISymbol> assignedInBlock,
            out HashSet<ISymbol> usedBeforeAssigned)
        {
            assignedInBlock = new HashSet<ISymbol>(); // Kill (The set of variables that are assigned a value.)
            usedBeforeAssigned = new HashSet<ISymbol>(); // Gen (The set of variables that are used before any assignment.)

            var assignmentLhs = new HashSet<SyntaxNode>();

            foreach (var instruction in block.Instructions.Reverse())
            {
                switch (instruction.Kind())
                {
                    case SyntaxKind.IdentifierName:
                        ProcessIdentifier(instruction, assignedInBlock, usedBeforeAssigned, assignmentLhs);
                        break;

                    case SyntaxKind.SimpleAssignmentExpression:
                        ProcessSimpleAssignment(instruction, assignedInBlock, usedBeforeAssigned, assignmentLhs);
                        break;

                    case SyntaxKind.VariableDeclarator:
                        ProcessVariableDeclarator(instruction, assignedInBlock, usedBeforeAssigned);
                        break;

                    case SyntaxKind.AnonymousMethodExpression:
                    case SyntaxKind.ParenthesizedLambdaExpression:
                    case SyntaxKind.SimpleLambdaExpression:
                    case SyntaxKind.QueryExpression:
                        CollectAllCapturedLocal(instruction);
                        break;

                    default:
                        break;
                }
            }

            if (block.Instructions.Any())
            {
                return;
            }

            // Variable declaration in a foreach statement is not a VariableDeclarator, so handling it separately:
            var foreachBlock = block as BinaryBranchBlock;
            if (foreachBlock != null &&
                foreachBlock.BranchingNode.IsKind(SyntaxKind.ForEachStatement))
            {
                var foreachNode = (ForEachStatementSyntax)foreachBlock.BranchingNode;
                ProcessVariableInForeach(foreachNode, assignedInBlock, usedBeforeAssigned);
            }
        }
Пример #9
0
        private bool AreAllSuccessorsValid(Block block)
        {
            alreadyVisitedBlocks.Add(block);

            if (block.SuccessorBlocks.Contains(cfg.ExitBlock) ||
                !block.SuccessorBlocks.Except(alreadyVisitedBlocks).Any())
            {
                return false;
            }

            return block.SuccessorBlocks
                .Except(alreadyVisitedBlocks)
                .All(b => IsBlockValidWithSuccessors(b));
        }
Пример #10
0
        private static ISet<Block> GetAll(Block initial, Func<Block, IEnumerable<Block>> getNexts)
        {
            var toProcess = new Queue<Block>();
            var alreadyProcesses = new HashSet<Block>();
            getNexts(initial).ToList().ForEach(b => toProcess.Enqueue(b));
            while (toProcess.Count != 0)
            {
                var current = toProcess.Dequeue();
                if (alreadyProcesses.Contains(current))
                {
                    continue;
                }

                alreadyProcesses.Add(current);

                getNexts(current).ToList().ForEach(b => toProcess.Enqueue(b));
            }

            return alreadyProcesses.ToImmutableHashSet();
        }
Пример #11
0
 private void VerifyInstructions(Block block, int fromIndex, params string[] instructions)
 {
     block.Instructions.Count.Should().BeGreaterOrEqualTo(fromIndex + instructions.Length);
     for (int i = 0; i < instructions.Length; i++)
     {
         block.Instructions[fromIndex + i].ToString().Should().BeEquivalentTo(instructions[i]);
     }
 }
Пример #12
0
 protected override bool IsBlockValid(Block block)
 {
     return BlockHasReferenceToDeclaringSymbol(block);
 }
Пример #13
0
 protected abstract bool BlockHasReferenceToDeclaringSymbol(Block block);
Пример #14
0
            protected override bool BlockHasReferenceToDeclaringSymbol(Block block)
            {
                return block.Instructions.Any(i =>
                {
                    var invocation = i as InvocationExpressionSyntax;
                    if (invocation == null)
                    {
                        return false;
                    }

                    return IsInstructionOnThisAndMatchesDeclaringSymbol(invocation.Expression);
                });
            }
Пример #15
0
 protected override bool BlockHasReferenceToDeclaringSymbol(Block block)
 {
     return block.Instructions.Any(i =>
         TypesForReference.Contains(i.GetType()) &&
         MatchesAccessor(i) &&
         IsInstructionOnThisAndMatchesDeclaringSymbol(i));
 }
Пример #16
0
 private void VerifyNoInstruction(Block block)
 {
     VerifyAllInstructions(block, new string[0]);
 }
Пример #17
0
 protected virtual bool IsBlockInvalid(Block block) { return false; }
Пример #18
0
 protected abstract void ProcessBlock(Block block, out HashSet<ISymbol> assignedInBlock,
     out HashSet<ISymbol> usedInBlock);
Пример #19
0
 private bool IsBlockValidWithSuccessors(Block block)
 {
     return !IsBlockInvalid(block) && (IsBlockValid(block) || AreAllSuccessorsValid(block));
 }
Пример #20
0
 public IReadOnlyList<ISymbol> GetLiveIn(Block block)
 {
     return liveInStates[block].Except(capturedVariables).ToImmutableArray();
 }
 internal BinaryBranchingSimpleBlock(SyntaxNode branchingInstruction, Block trueAndFalseSuccessor)
     : base(trueAndFalseSuccessor)
 {
     BranchingInstruction = branchingInstruction;
 }
Пример #22
0
 private void VerifyAllInstructions(Block block, params string[] instructions)
 {
     block.Instructions.Count.ShouldBeEquivalentTo(instructions.Count());
     VerifyInstructions(block, 0, instructions);
 }
Пример #23
0
 private static void CheckCfgBlockForDeadStores(Block block, IEnumerable<ISymbol> blockOutState, IEnumerable<ISymbol> excludedLocals, CSharpSyntaxNode node,
     ISymbol declaration, SyntaxNodeAnalysisContext context)
 {
     var lva = new InBlockLivenessAnalysis(block, blockOutState, excludedLocals, node, declaration, context);
     lva.Analyze();
 }
Пример #24
0
 public InBlockLivenessAnalysis(Block block, IEnumerable<ISymbol> blockOutState, IEnumerable<ISymbol> excludedLocals, CSharpSyntaxNode node, ISymbol declaration,
     SyntaxNodeAnalysisContext context)
 {
     this.block = block;
     this.blockOutState = blockOutState;
     this.node = node;
     this.declaration = declaration;
     this.context = context;
     this.excludedLocals = excludedLocals;
 }