private ISet <VariableAlias> _CollectAliases(string source) { var semanticModel = _documentFactory.CreateSemanticModel(source); var forStatement = semanticModel.SyntaxTree.GetRoot().DescendantNodes().OfType <ForStatementSyntax>().Single(); var code = CodeFactory.Create(forStatement, semanticModel); var variableAccesses = VariableAccesses.Collect(code); var cfg = ControlFlowGraphFactory.Create(code); return(ExternalArrayAliasCollector.Collect(semanticModel, forStatement, variableAccesses)); }
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)); }
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); }
/// <summary> /// Checks that there are no write accesses to shared variables. /// </summary> /// <param name="variableAccesses">A prelimary applied variable access collection on the loop's body.</param> /// <returns><code>True</code> if there are no write accesses to shared variables.</returns> public static bool HasNoWriteAccessToSharedVariables(VariableAccesses variableAccesses) { return(!new WriteAccessVerifier(variableAccesses)._ContainsWriteAccessesToSharedVariables()); }
private WriteAccessVerifier(VariableAccesses variableAccesses) { _variableAccesses = variableAccesses; }
private VariableAccesses _CollectAccesses(string body) { return(VariableAccesses.Collect(TestCodeFactory.CreateCode(body))); }
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); }