private bool _HasConflictingArrayAccesses(TLoopStatementSyntax loopStatement, string loopIndex, Code code, VariableAccesses variableAccesses) { var optimized = OptimizationRunner.Optimize(code); code = optimized.Code; variableAccesses = optimized.Changed ? VariableAccesses.Collect(code) : variableAccesses; var cfg = ControlFlowGraphFactory.Create(code, true); var callGraph = CallGraphFactory.Create(cfg, _methods); var calledMethods = callGraph.Methods.Select(methodName => _methods[methodName]).ToImmutableList(); var aliasAnalysis = AliasAnalysis.Analyze(cfg, callGraph, _methods.Values, _GetAliasesAtLoopEntry(loopStatement, variableAccesses)); return(ArrayAccessVerifier.HasConflictingAccesses(loopIndex, cfg, aliasAnalysis, callGraph, calledMethods)); }
private IEnumerable <VariableAlias> _GetAliasesAtLoopEntry(TLoopStatementSyntax loopStatement, VariableAccesses variableAccesses) { // TODO maybe use a different Expression to setup the input aliases instead of variables. This might cause trouble when forgetting this situation in further changes. var filtered = variableAccesses.DeclaredVariables .Concat(variableAccesses.ReadArrays.Concat(variableAccesses.WrittenArrays).Select(array => array.Name)) .ToImmutableHashSet(); var variables = variableAccesses.ReadVariables .Union(variableAccesses.WrittenVariables) .Except(filtered) .Select(variableName => new VariableAlias(variableName, new VariableExpression(variableName))) .Concat(ExternalArrayAliasCollector.Collect(_semanticModel, loopStatement, variableAccesses)) .ToImmutableHashSet(); return(variables); }
public void Scan(TLoopStatementSyntax loopStatement, SyntaxNode body, string loopIndex, Location location) { var code = ThreeAddressCodeFactory.Create(CodeFactory.Create(body, _semanticModel)); var variableAccesses = VariableAccesses.Collect(code); if (!WriteAccessVerifier.HasNoWriteAccessToSharedVariables(variableAccesses)) { Debug.WriteLine("the loop contains write accesses to shared variables"); return; } if (_HasConflictingArrayAccesses(loopStatement, loopIndex, code, variableAccesses)) { Debug.WriteLine("the loop contains loop carried dependencies"); return; } _ReportLoopForParallelization(loopStatement, location); }
private void _ReportLoopForParallelization(TLoopStatementSyntax loopStatement, Location location) { var diagnostic = Diagnostic.Create(_rule, location, ImmutableList.Create(loopStatement.GetLocation())); _context.ReportDiagnostic(diagnostic); }