提交 1aa7e2cd 编写于 作者: M Manish Vasani

Address review feedback

上级 3f0b73c0
...@@ -24,7 +24,7 @@ public static BitVector Run(ControlFlowGraph controlFlowGraph) ...@@ -24,7 +24,7 @@ public static BitVector Run(ControlFlowGraph controlFlowGraph)
public override bool AnalyzeBlock(BasicBlock basicBlock, CancellationToken cancellationToken) public override bool AnalyzeBlock(BasicBlock basicBlock, CancellationToken cancellationToken)
{ {
SetCurrentAnalysisData(basicBlock, isReachable: true); SetCurrentAnalysisData(basicBlock, isReachable: true, cancellationToken);
return true; return true;
} }
...@@ -54,7 +54,7 @@ public override bool AnalyzeNonConditionalBranch(BasicBlock basicBlock, bool cur ...@@ -54,7 +54,7 @@ public override bool AnalyzeNonConditionalBranch(BasicBlock basicBlock, bool cur
return (currentIsReachable, currentIsReachable); return (currentIsReachable, currentIsReachable);
} }
public override void SetCurrentAnalysisData(BasicBlock basicBlock, bool isReachable) public override void SetCurrentAnalysisData(BasicBlock basicBlock, bool isReachable, CancellationToken cancellationToken)
{ {
_visited[basicBlock.Ordinal] = isReachable; _visited[basicBlock.Ordinal] = isReachable;
} }
......
...@@ -79,7 +79,7 @@ public static TBlockAnalysisData Run(ControlFlowGraph controlFlowGraph, DataFlow ...@@ -79,7 +79,7 @@ public static TBlockAnalysisData Run(ControlFlowGraph controlFlowGraph, DataFlow
var toVisit = new SortedSet<int>(); var toVisit = new SortedSet<int>();
var firstBlock = blocks[firstBlockOrdinal]; var firstBlock = blocks[firstBlockOrdinal];
analyzer.SetCurrentAnalysisData(firstBlock, initialAnalysisData); analyzer.SetCurrentAnalysisData(firstBlock, initialAnalysisData, cancellationToken);
toVisit.Add(firstBlock.Ordinal); toVisit.Add(firstBlock.Ordinal);
var processedBlocks = PooledHashSet<BasicBlock>.GetInstance(); var processedBlocks = PooledHashSet<BasicBlock>.GetInstance();
...@@ -122,7 +122,7 @@ public static TBlockAnalysisData Run(ControlFlowGraph controlFlowGraph, DataFlow ...@@ -122,7 +122,7 @@ public static TBlockAnalysisData Run(ControlFlowGraph controlFlowGraph, DataFlow
continue; continue;
} }
analyzer.SetCurrentAnalysisData(current, analyzer.GetEmptyAnalysisData()); analyzer.SetCurrentAnalysisData(current, analyzer.GetEmptyAnalysisData(), cancellationToken);
} }
if (current.Ordinal < firstBlockOrdinal || current.Ordinal > lastBlockOrdinal) if (current.Ordinal < firstBlockOrdinal || current.Ordinal > lastBlockOrdinal)
...@@ -238,7 +238,7 @@ void FollowBranch(BasicBlock current, ControlFlowBranch branch, TBlockAnalysisDa ...@@ -238,7 +238,7 @@ void FollowBranch(BasicBlock current, ControlFlowBranch branch, TBlockAnalysisDa
if ((current.IsReachable || !destination.IsReachable) && if ((current.IsReachable || !destination.IsReachable) &&
(!analyzer.IsEqual(currentDestinationData, mergedAnalysisData) || !processedBlocks.Contains(destination))) (!analyzer.IsEqual(currentDestinationData, mergedAnalysisData) || !processedBlocks.Contains(destination)))
{ {
analyzer.SetCurrentAnalysisData(destination, mergedAnalysisData); analyzer.SetCurrentAnalysisData(destination, mergedAnalysisData, cancellationToken);
toVisit.Add(branch.Destination.Ordinal); toVisit.Add(branch.Destination.Ordinal);
} }
} }
......
...@@ -24,7 +24,7 @@ internal abstract class DataFlowAnalyzer<TBlockAnalysisData> : IDisposable ...@@ -24,7 +24,7 @@ internal abstract class DataFlowAnalyzer<TBlockAnalysisData> : IDisposable
/// <summary> /// <summary>
/// Updates the current analysis data for the given basic block. /// Updates the current analysis data for the given basic block.
/// </summary> /// </summary>
public abstract void SetCurrentAnalysisData(BasicBlock basicBlock, TBlockAnalysisData data); public abstract void SetCurrentAnalysisData(BasicBlock basicBlock, TBlockAnalysisData data, CancellationToken cancellationToken);
/// <summary> /// <summary>
/// Analyze the given basic block and return the block analysis data at the end of the block for its successors. /// Analyze the given basic block and return the block analysis data at the end of the block for its successors.
......
...@@ -156,24 +156,24 @@ private sealed class FlowGraphAnalysisData : AnalysisData ...@@ -156,24 +156,24 @@ private sealed class FlowGraphAnalysisData : AnalysisData
public BasicBlockAnalysisData GetBlockAnalysisData(BasicBlock basicBlock) public BasicBlockAnalysisData GetBlockAnalysisData(BasicBlock basicBlock)
=> _analysisDataByBasicBlockMap[basicBlock]; => _analysisDataByBasicBlockMap[basicBlock];
public BasicBlockAnalysisData GetOrCreateBlockAnalysisData(BasicBlock basicBlock) public BasicBlockAnalysisData GetOrCreateBlockAnalysisData(BasicBlock basicBlock, CancellationToken cancellationToken)
{ {
if (_analysisDataByBasicBlockMap[basicBlock] == null) if (_analysisDataByBasicBlockMap[basicBlock] == null)
{ {
_analysisDataByBasicBlockMap[basicBlock] = CreateBlockAnalysisData(); _analysisDataByBasicBlockMap[basicBlock] = CreateBlockAnalysisData();
} }
HandleCatchOrFilterOrFinallyInitialization(basicBlock); HandleCatchOrFilterOrFinallyInitialization(basicBlock, cancellationToken);
return _analysisDataByBasicBlockMap[basicBlock]; return _analysisDataByBasicBlockMap[basicBlock];
} }
private PooledHashSet<(ISymbol, IOperation)> GetOrCreateSymbolWritesInBlockRange(int firstBlockOrdinal, int lastBlockOrdinal) private PooledHashSet<(ISymbol, IOperation)> GetOrCreateSymbolWritesInBlockRange(int firstBlockOrdinal, int lastBlockOrdinal, CancellationToken cancellationToken)
{ {
if (!_symbolWritesInsideBlockRangeMap.TryGetValue((firstBlockOrdinal, lastBlockOrdinal), out var writesInBlockRange)) if (!_symbolWritesInsideBlockRangeMap.TryGetValue((firstBlockOrdinal, lastBlockOrdinal), out var writesInBlockRange))
{ {
// Compute all descendant operations in basic block range. // Compute all descendant operations in basic block range.
var operations = PooledHashSet<IOperation>.GetInstance(); var operations = PooledHashSet<IOperation>.GetInstance();
AddOperationsInRange(ControlFlowGraph, firstBlockOrdinal, lastBlockOrdinal, operations); AddDescendantOperationsInRange(ControlFlowGraph, firstBlockOrdinal, lastBlockOrdinal, operations, cancellationToken);
// Filter down the operations to writes within this block range. // Filter down the operations to writes within this block range.
writesInBlockRange = PooledHashSet<(ISymbol, IOperation)>.GetInstance(); writesInBlockRange = PooledHashSet<(ISymbol, IOperation)>.GetInstance();
...@@ -189,15 +189,17 @@ private PooledHashSet<(ISymbol, IOperation)> GetOrCreateSymbolWritesInBlockRange ...@@ -189,15 +189,17 @@ private PooledHashSet<(ISymbol, IOperation)> GetOrCreateSymbolWritesInBlockRange
return writesInBlockRange; return writesInBlockRange;
} }
private void AddOperationsInRange( private void AddDescendantOperationsInRange(
ControlFlowGraph cfg, ControlFlowGraph cfg,
int firstBlockOrdinal, int firstBlockOrdinal,
int lastBlockOrdinal, int lastBlockOrdinal,
PooledHashSet<IOperation> operationsBuilder) PooledHashSet<IOperation> operationsBuilder,
CancellationToken cancellationToken)
{ {
// Compute all descendant operations in basic block range. // Compute all descendant operations in basic block range.
for (int i = firstBlockOrdinal; i <= lastBlockOrdinal; i++) for (int i = firstBlockOrdinal; i <= lastBlockOrdinal; i++)
{ {
cancellationToken.ThrowIfCancellationRequested();
foreach (var operation in cfg.Blocks[i].DescendantOperations()) foreach (var operation in cfg.Blocks[i].DescendantOperations())
{ {
var added = operationsBuilder.Add(operation); var added = operationsBuilder.Add(operation);
...@@ -206,14 +208,14 @@ private PooledHashSet<(ISymbol, IOperation)> GetOrCreateSymbolWritesInBlockRange ...@@ -206,14 +208,14 @@ private PooledHashSet<(ISymbol, IOperation)> GetOrCreateSymbolWritesInBlockRange
if (invocation.Instance != null && if (invocation.Instance != null &&
_reachingDelegateCreationTargets.TryGetValue(invocation.Instance, out var targets)) _reachingDelegateCreationTargets.TryGetValue(invocation.Instance, out var targets))
{ {
AddOperationsFromDelegateCreationTargets(targets); AddDescendantOperationsFromDelegateCreationTargets(targets);
} }
else if (invocation.TargetMethod.IsLocalFunction()) else if (invocation.TargetMethod.IsLocalFunction())
{ {
var localFunctionGraph = cfg.GetLocalFunctionControlFlowGraphInScope(invocation.TargetMethod); var localFunctionGraph = cfg.GetLocalFunctionControlFlowGraphInScope(invocation.TargetMethod);
if (localFunctionGraph != null) if (localFunctionGraph != null)
{ {
AddOperationsInLambdaOrLocalFunctionGraph(localFunctionGraph); AddDescendantOperationsInLambdaOrLocalFunctionGraph(localFunctionGraph);
} }
} }
} }
...@@ -223,7 +225,7 @@ private PooledHashSet<(ISymbol, IOperation)> GetOrCreateSymbolWritesInBlockRange ...@@ -223,7 +225,7 @@ private PooledHashSet<(ISymbol, IOperation)> GetOrCreateSymbolWritesInBlockRange
return; return;
// Local functions. // Local functions.
void AddOperationsFromDelegateCreationTargets(PooledHashSet<IOperation> targets) void AddDescendantOperationsFromDelegateCreationTargets(PooledHashSet<IOperation> targets)
{ {
foreach (var target in targets) foreach (var target in targets)
{ {
...@@ -246,15 +248,16 @@ void AddOperationsFromDelegateCreationTargets(PooledHashSet<IOperation> targets) ...@@ -246,15 +248,16 @@ void AddOperationsFromDelegateCreationTargets(PooledHashSet<IOperation> targets)
if (lambdaOrLocalFunctionCfgOpt != null && if (lambdaOrLocalFunctionCfgOpt != null &&
operationsBuilder.Add(target)) operationsBuilder.Add(target))
{ {
AddOperationsInLambdaOrLocalFunctionGraph(lambdaOrLocalFunctionCfgOpt); AddDescendantOperationsInLambdaOrLocalFunctionGraph(lambdaOrLocalFunctionCfgOpt);
} }
} }
} }
void AddOperationsInLambdaOrLocalFunctionGraph(ControlFlowGraph lambdaOrLocalFunctionCfg) void AddDescendantOperationsInLambdaOrLocalFunctionGraph(ControlFlowGraph lambdaOrLocalFunctionCfg)
{ {
Debug.Assert(lambdaOrLocalFunctionCfg != null); Debug.Assert(lambdaOrLocalFunctionCfg != null);
AddOperationsInRange(lambdaOrLocalFunctionCfg, firstBlockOrdinal: 0, lastBlockOrdinal: lambdaOrLocalFunctionCfg.Blocks.Length - 1, operationsBuilder); AddDescendantOperationsInRange(lambdaOrLocalFunctionCfg, firstBlockOrdinal: 0,
lastBlockOrdinal: lambdaOrLocalFunctionCfg.Blocks.Length - 1, operationsBuilder, cancellationToken);
} }
ControlFlowGraph TryGetAnonymousFunctionControlFlowGraphInScope(IFlowAnonymousFunctionOperation flowAnonymousFunctionOperation) ControlFlowGraph TryGetAnonymousFunctionControlFlowGraphInScope(IFlowAnonymousFunctionOperation flowAnonymousFunctionOperation)
...@@ -289,7 +292,7 @@ ControlFlowGraph TryGetLocalFunctionControlFlowGraphInScope(IMethodSymbol localF ...@@ -289,7 +292,7 @@ ControlFlowGraph TryGetLocalFunctionControlFlowGraphInScope(IMethodSymbol localF
/// catch/filter/finally region. /// catch/filter/finally region.
/// </summary> /// </summary>
/// <param name="basicBlock"></param> /// <param name="basicBlock"></param>
private void HandleCatchOrFilterOrFinallyInitialization(BasicBlock basicBlock) private void HandleCatchOrFilterOrFinallyInitialization(BasicBlock basicBlock, CancellationToken cancellationToken)
{ {
Debug.Assert(_analysisDataByBasicBlockMap[basicBlock] != null); Debug.Assert(_analysisDataByBasicBlockMap[basicBlock] != null);
...@@ -347,7 +350,7 @@ private void HandleCatchOrFilterOrFinallyInitialization(BasicBlock basicBlock) ...@@ -347,7 +350,7 @@ private void HandleCatchOrFilterOrFinallyInitialization(BasicBlock basicBlock)
mergedAnalysisData.SetAnalysisDataFrom(GetBlockAnalysisData(firstBasicBlockInOutermostRegion)); mergedAnalysisData.SetAnalysisDataFrom(GetBlockAnalysisData(firstBasicBlockInOutermostRegion));
// All symbol writes within the try region are considered reachable at start of catch/finally region. // All symbol writes within the try region are considered reachable at start of catch/finally region.
foreach (var (symbol, write) in GetOrCreateSymbolWritesInBlockRange(containingTryCatchFinallyRegion.FirstBlockOrdinal, basicBlock.Ordinal - 1)) foreach (var (symbol, write) in GetOrCreateSymbolWritesInBlockRange(containingTryCatchFinallyRegion.FirstBlockOrdinal, basicBlock.Ordinal - 1, cancellationToken))
{ {
mergedAnalysisData.OnWriteReferenceFound(symbol, write, maybeWritten: true); mergedAnalysisData.OnWriteReferenceFound(symbol, write, maybeWritten: true);
SymbolsWriteBuilder[(symbol, write)] = true; SymbolsWriteBuilder[(symbol, write)] = true;
...@@ -357,8 +360,8 @@ private void HandleCatchOrFilterOrFinallyInitialization(BasicBlock basicBlock) ...@@ -357,8 +360,8 @@ private void HandleCatchOrFilterOrFinallyInitialization(BasicBlock basicBlock)
SetBlockAnalysisData(basicBlock, mergedAnalysisData); SetBlockAnalysisData(basicBlock, mergedAnalysisData);
} }
public void SetCurrentBlockAnalysisDataFrom(BasicBlock basicBlock) public void SetCurrentBlockAnalysisDataFrom(BasicBlock basicBlock, CancellationToken cancellationToken)
=> SetCurrentBlockAnalysisDataFrom(GetOrCreateBlockAnalysisData(basicBlock)); => SetCurrentBlockAnalysisDataFrom(GetOrCreateBlockAnalysisData(basicBlock, cancellationToken));
public void SetAnalysisDataOnEntryBlockStart() public void SetAnalysisDataOnEntryBlockStart()
{ {
...@@ -372,8 +375,8 @@ public void SetAnalysisDataOnEntryBlockStart() ...@@ -372,8 +375,8 @@ public void SetAnalysisDataOnEntryBlockStart()
public void SetBlockAnalysisData(BasicBlock basicBlock, BasicBlockAnalysisData data) public void SetBlockAnalysisData(BasicBlock basicBlock, BasicBlockAnalysisData data)
=> _analysisDataByBasicBlockMap[basicBlock] = data; => _analysisDataByBasicBlockMap[basicBlock] = data;
public void SetBlockAnalysisDataFrom(BasicBlock basicBlock, BasicBlockAnalysisData data) public void SetBlockAnalysisDataFrom(BasicBlock basicBlock, BasicBlockAnalysisData data, CancellationToken cancellationToken)
=> GetOrCreateBlockAnalysisData(basicBlock).SetAnalysisDataFrom(data); => GetOrCreateBlockAnalysisData(basicBlock, cancellationToken).SetAnalysisDataFrom(data);
public void SetAnalysisDataOnExitBlockEnd() public void SetAnalysisDataOnExitBlockEnd()
{ {
......
...@@ -17,22 +17,18 @@ internal static partial class SymbolUsageAnalysis ...@@ -17,22 +17,18 @@ internal static partial class SymbolUsageAnalysis
private sealed partial class DataFlowAnalyzer : DataFlowAnalyzer<BasicBlockAnalysisData> private sealed partial class DataFlowAnalyzer : DataFlowAnalyzer<BasicBlockAnalysisData>
{ {
private readonly FlowGraphAnalysisData _analysisData; private readonly FlowGraphAnalysisData _analysisData;
private readonly CancellationToken _cancellationToken;
private DataFlowAnalyzer(ControlFlowGraph cfg, ISymbol owningSymbol, CancellationToken cancellationToken) private DataFlowAnalyzer(ControlFlowGraph cfg, ISymbol owningSymbol)
{ {
_analysisData = FlowGraphAnalysisData.Create(cfg, owningSymbol, AnalyzeLocalFunctionOrLambdaInvocation); _analysisData = FlowGraphAnalysisData.Create(cfg, owningSymbol, AnalyzeLocalFunctionOrLambdaInvocation);
_cancellationToken = cancellationToken;
} }
private DataFlowAnalyzer( private DataFlowAnalyzer(
ControlFlowGraph cfg, ControlFlowGraph cfg,
IMethodSymbol lambdaOrLocalFunction, IMethodSymbol lambdaOrLocalFunction,
FlowGraphAnalysisData parentAnalysisData, FlowGraphAnalysisData parentAnalysisData)
CancellationToken cancellationToken)
{ {
_analysisData = FlowGraphAnalysisData.Create(cfg, lambdaOrLocalFunction, parentAnalysisData); _analysisData = FlowGraphAnalysisData.Create(cfg, lambdaOrLocalFunction, parentAnalysisData);
_cancellationToken = cancellationToken;
var entryBlockAnalysisData = GetEmptyAnalysisData(); var entryBlockAnalysisData = GetEmptyAnalysisData();
entryBlockAnalysisData.SetAnalysisDataFrom(parentAnalysisData.CurrentBlockAnalysisData); entryBlockAnalysisData.SetAnalysisDataFrom(parentAnalysisData.CurrentBlockAnalysisData);
...@@ -42,7 +38,7 @@ private DataFlowAnalyzer(ControlFlowGraph cfg, ISymbol owningSymbol, Cancellatio ...@@ -42,7 +38,7 @@ private DataFlowAnalyzer(ControlFlowGraph cfg, ISymbol owningSymbol, Cancellatio
public static SymbolUsageResult RunAnalysis(ControlFlowGraph cfg, ISymbol owningSymbol, CancellationToken cancellationToken) public static SymbolUsageResult RunAnalysis(ControlFlowGraph cfg, ISymbol owningSymbol, CancellationToken cancellationToken)
{ {
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
using (var analyzer = new DataFlowAnalyzer(cfg, owningSymbol, cancellationToken)) using (var analyzer = new DataFlowAnalyzer(cfg, owningSymbol))
{ {
_ = CustomDataFlowAnalysis<BasicBlockAnalysisData>.Run(cfg, analyzer, cancellationToken); _ = CustomDataFlowAnalysis<BasicBlockAnalysisData>.Run(cfg, analyzer, cancellationToken);
return analyzer._analysisData.ToResult(); return analyzer._analysisData.ToResult();
...@@ -61,7 +57,7 @@ public override void Dispose() ...@@ -61,7 +57,7 @@ public override void Dispose()
Debug.Assert(localFunctionOrLambda.IsLocalFunction() || localFunctionOrLambda.IsAnonymousFunction()); Debug.Assert(localFunctionOrLambda.IsLocalFunction() || localFunctionOrLambda.IsAnonymousFunction());
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
using (var analyzer = new DataFlowAnalyzer(cfg, localFunctionOrLambda, (FlowGraphAnalysisData)parentAnalysisData, cancellationToken)) using (var analyzer = new DataFlowAnalyzer(cfg, localFunctionOrLambda, (FlowGraphAnalysisData)parentAnalysisData))
{ {
var resultBlockAnalysisData = CustomDataFlowAnalysis<BasicBlockAnalysisData>.Run(cfg, analyzer, cancellationToken); var resultBlockAnalysisData = CustomDataFlowAnalysis<BasicBlockAnalysisData>.Run(cfg, analyzer, cancellationToken);
if (resultBlockAnalysisData == null) if (resultBlockAnalysisData == null)
...@@ -101,7 +97,7 @@ public override BasicBlockAnalysisData AnalyzeBlock(BasicBlock basicBlock, Cance ...@@ -101,7 +97,7 @@ public override BasicBlockAnalysisData AnalyzeBlock(BasicBlock basicBlock, Cance
void BeforeBlockAnalysis() void BeforeBlockAnalysis()
{ {
// Initialize current block analysis data. // Initialize current block analysis data.
_analysisData.SetCurrentBlockAnalysisDataFrom(basicBlock); _analysisData.SetCurrentBlockAnalysisDataFrom(basicBlock, cancellationToken);
// At start of entry block, handle parameter definitions from method declaration. // At start of entry block, handle parameter definitions from method declaration.
if (basicBlock.Kind == BasicBlockKind.Entry) if (basicBlock.Kind == BasicBlockKind.Entry)
...@@ -155,8 +151,8 @@ public override BasicBlockAnalysisData GetCurrentAnalysisData(BasicBlock basicBl ...@@ -155,8 +151,8 @@ public override BasicBlockAnalysisData GetCurrentAnalysisData(BasicBlock basicBl
public override BasicBlockAnalysisData GetEmptyAnalysisData() public override BasicBlockAnalysisData GetEmptyAnalysisData()
=> _analysisData.CreateBlockAnalysisData(); => _analysisData.CreateBlockAnalysisData();
public override void SetCurrentAnalysisData(BasicBlock basicBlock, BasicBlockAnalysisData data) public override void SetCurrentAnalysisData(BasicBlock basicBlock, BasicBlockAnalysisData data, CancellationToken cancellationToken)
=> _analysisData.SetBlockAnalysisDataFrom(basicBlock, data); => _analysisData.SetBlockAnalysisDataFrom(basicBlock, data, cancellationToken);
public override bool IsEqual(BasicBlockAnalysisData analysisData1, BasicBlockAnalysisData analysisData2) public override bool IsEqual(BasicBlockAnalysisData analysisData1, BasicBlockAnalysisData analysisData2)
=> analysisData1 == null ? analysisData2 == null : analysisData1.Equals(analysisData2); => analysisData1 == null ? analysisData2 == null : analysisData1.Equals(analysisData2);
......
...@@ -173,6 +173,7 @@ private bool MakePendingWrite(IOperation operation, ISymbol symbolOpt) ...@@ -173,6 +173,7 @@ private bool MakePendingWrite(IOperation operation, ISymbol symbolOpt)
return false; return false;
} }
private void ProcessPendingWritesForAssignmentTarget(IAssignmentOperation operation) private void ProcessPendingWritesForAssignmentTarget(IAssignmentOperation operation)
{ {
if (_pendingWritesMap.TryGetValue(operation, out var pendingWrites)) if (_pendingWritesMap.TryGetValue(operation, out var pendingWrites))
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册