예제 #1
0
 public abstract TBlockAnalysisData AnalyzeNonConditionalBranch(
     BasicBlock basicBlock,
     TBlockAnalysisData currentAnalysisData,
     CancellationToken cancellationToken
     );
예제 #2
0
 public abstract (TBlockAnalysisData fallThroughSuccessorData, TBlockAnalysisData conditionalSuccessorData) AnalyzeConditionalBranch(
     BasicBlock basicBlock,
     TBlockAnalysisData currentAnalysisData,
     CancellationToken cancellationToken
     );
예제 #3
0
 public abstract void SetCurrentAnalysisData(
     BasicBlock basicBlock,
     TBlockAnalysisData data,
     CancellationToken cancellationToken
     );
예제 #4
0
 public abstract TBlockAnalysisData AnalyzeBlock(
     BasicBlock basicBlock,
     CancellationToken cancellationToken
     );
예제 #5
0
 /// <summary>
 /// Returns true if the given basic block is the last block of a finally region.
 /// </summary>
 public static bool IsLastBlockOfFinally(this BasicBlock basicBlock, out ControlFlowRegion finallyRegion)
 => basicBlock.IsLastBlockOfRegionKind(ControlFlowRegionKind.Finally, out finallyRegion);
예제 #6
0
 public abstract TBlockAnalysisData GetCurrentAnalysisData(BasicBlock basicBlock);
예제 #7
0
 /// <summary>
 /// Gets the maximum ordinal of a conditional or fall through successor of the given basic block.
 /// Returns -1 if the block has no conditional or fall through successor,
 /// for example, if the block only has a structured exception handling branch for throw operation.
 /// </summary>
 /// <param name="basicBlock"></param>
 /// <returns></returns>
 internal static int GetMaxSuccessorOrdinal(this BasicBlock basicBlock)
 => Math.Max(basicBlock.FallThroughSuccessor?.Destination?.Ordinal ?? -1,
             basicBlock.ConditionalSuccessor?.Destination?.Ordinal ?? -1);
예제 #8
0
 /// <summary>
 /// Returns true if the given basic block is the first block of a finally region.
 /// </summary>
 public static bool IsFirstBlockOfFinally(this BasicBlock basicBlock, [NotNullWhen(returnValue: true)] out ControlFlowRegion?finallyRegion)
 => basicBlock.IsFirstBlockOfRegionKind(ControlFlowRegionKind.Finally, out finallyRegion);
예제 #9
0
 internal static IEnumerable <(BasicBlock predecessorBlock, BranchWithInfo branchWithInfo)> GetPredecessorsWithBranches(this BasicBlock basicBlock, ControlFlowGraph cfg)
 {
     foreach (ControlFlowBranch predecessorBranch in basicBlock.Predecessors)
     {
         var branchWithInfo = new BranchWithInfo(predecessorBranch);
         if (predecessorBranch.FinallyRegions.Length > 0)
         {
             var lastFinally = predecessorBranch.FinallyRegions[predecessorBranch.FinallyRegions.Length - 1];
             yield return(predecessorBlock : cfg.Blocks[lastFinally.LastBlockOrdinal], branchWithInfo);
         }
         else
         {
             yield return(predecessorBlock : predecessorBranch.Source, branchWithInfo);
         }
     }
 }
예제 #10
0
 /// <summary>
 /// Returns true if the given basic block is the last block of a region of the given regionKind.
 /// </summary>
 public static bool IsLastBlockOfRegionKind(this BasicBlock basicBlock, ControlFlowRegionKind regionKind, out ControlFlowRegion region)
 => basicBlock.IsFirstOrLastBlockOfRegionKind(regionKind, first: false, out region);
 public override bool GetCurrentAnalysisData(BasicBlock basicBlock) => _visited[basicBlock.Ordinal];
 public override void SetCurrentAnalysisData(BasicBlock basicBlock, bool isReachable, CancellationToken cancellationToken)
 {
     _visited[basicBlock.Ordinal] = isReachable;
 }
 public override bool AnalyzeBlock(BasicBlock basicBlock, CancellationToken cancellationToken)
 {
     SetCurrentAnalysisData(basicBlock, isReachable: true, cancellationToken);
     return(true);
 }
            public ImmutableArray <ControlFlowBranch> ConvertPredecessorsToBranches(ArrayBuilder <BasicBlock> blocks)
            {
                if (!HasPredecessors)
                {
                    _predecessors?.Free();
                    _predecessors = null;
                    return(ImmutableArray <ControlFlowBranch> .Empty);
                }

                BasicBlock block = blocks[Ordinal];

                var branches = ArrayBuilder <ControlFlowBranch> .GetInstance(_predecessors?.Count ?? 2);

                if (_predecessors != null)
                {
                    Debug.Assert(_predecessor1 == null);
                    Debug.Assert(_predecessor2 == null);

                    foreach (BasicBlockBuilder predecessorBlockBuilder in _predecessors)
                    {
                        addBranches(predecessorBlockBuilder);
                    }

                    _predecessors.Free();
                    _predecessors = null;
                }
                else
                {
                    if (_predecessor1 != null)
                    {
                        addBranches(_predecessor1);
                        _predecessor1 = null;
                    }

                    if (_predecessor2 != null)
                    {
                        addBranches(_predecessor2);
                        _predecessor2 = null;
                    }
                }

                // Order predecessors by source ordinal and conditional first to ensure deterministic predecessor ordering.
                branches.Sort((x, y) =>
                {
                    int result = x.Source.Ordinal - y.Source.Ordinal;
                    if (result == 0 && x.IsConditionalSuccessor != y.IsConditionalSuccessor)
                    {
                        if (x.IsConditionalSuccessor)
                        {
                            result = -1;
                        }
                        else
                        {
                            result = 1;
                        }
                    }

                    return(result);
                });

                return(branches.ToImmutableAndFree());

                void addBranches(BasicBlockBuilder predecessorBlockBuilder)
                {
                    BasicBlock predecessor = blocks[predecessorBlockBuilder.Ordinal];

                    Debug.Assert(predecessor.FallThroughSuccessor != null);
                    if (predecessor.FallThroughSuccessor.Destination == block)
                    {
                        branches.Add(predecessor.FallThroughSuccessor);
                    }

                    if (predecessor.ConditionalSuccessor?.Destination == block)
                    {
                        branches.Add(predecessor.ConditionalSuccessor);
                    }
                }
            }
예제 #15
0
 /// <summary>
 /// Returns true if the given <paramref name="basicBlock"/> is contained in a control flow region with the given <paramref name="regionKind"/>.
 /// </summary>
 public static bool IsContainedInRegionOfKind(this BasicBlock basicBlock, ControlFlowRegionKind regionKind)
 => basicBlock.GetContainingRegionOfKind(regionKind) != null;
 internal static IEnumerable <(BasicBlock predecessorBlock, BranchWithInfo branchWithInfo)> GetPredecessorsWithBranches(this BasicBlock basicBlock, ControlFlowGraph cfg)
 {
     foreach (ControlFlowBranch predecessorBranch in basicBlock.Predecessors)
     {
         var branchWithInfo = new BranchWithInfo(predecessorBranch);
         if (!predecessorBranch.FinallyRegions.IsEmpty)
         {
             var lastFinally = predecessorBranch.FinallyRegions[^ 1];
예제 #17
0
 /// <summary>
 /// Returns true if the given basic block is the last block of a region of the given regionKind.
 /// </summary>
 public static bool IsLastBlockOfRegionKind(this BasicBlock basicBlock, ControlFlowRegionKind regionKind, [NotNullWhen(returnValue: true)] out ControlFlowRegion?region)
 => basicBlock.IsFirstOrLastBlockOfRegionKind(regionKind, first: false, out region);