private bool HasAnyCommonLoops(IExpression expr, IExpression expr2) { List <IStatement> targetLoops = Containers.GetLoopsNeededForExpression(context, expr, -1, false); List <IStatement> indexLoops = Containers.GetLoopsNeededForExpression(context, expr2, -1, false); return(indexLoops.Any(loop => Containers.ListContains(targetLoops, loop))); }
private bool AreLoopsDisjoint(IForStatement loop, IExpression expr, IExpression expr2) { List <IStatement> targetLoops = Containers.GetLoopsNeededForExpression(context, expr, -1, false); List <IStatement> indexLoops = Containers.GetLoopsNeededForExpression(context, expr2, -1, false); Set <IStatement> parentLoops = new Set <IStatement>(); parentLoops.AddRange(targetLoops); parentLoops.AddRange(indexLoops); if (Containers.ListContains(parentLoops, loop)) { // expression has the form array[k][indices[k]] or array[indices[k][k]] return(false); } return(true); }
protected override IExpression ConvertMethodInvoke(IMethodInvokeExpression imie) { IExpression result = base.ConvertMethodInvoke(imie); if (result is IMethodInvokeExpression) { imie = (IMethodInvokeExpression)result; } else { return(result); } if (UseJaggedSubarray && Recognizer.IsStaticGenericMethod(imie, new Func <IReadOnlyList <PlaceHolder>, IReadOnlyList <int>, IReadOnlyList <PlaceHolder> >(Collection.Subarray))) { // check for the form Subarray(arrayExpr, indices[i]) where arrayExpr does not depend on i IExpression arrayExpr = imie.Arguments[0]; IExpression arg1 = imie.Arguments[1]; if (arg1 is IArrayIndexerExpression) { IArrayIndexerExpression index = (IArrayIndexerExpression)arg1; if (index.Indices.Count == 1 && index.Indices[0] is IVariableReferenceExpression) { // index has the form indices[i] List <IStatement> targetLoops = Containers.GetLoopsNeededForExpression(context, arrayExpr, -1, false); List <IStatement> indexLoops = Containers.GetLoopsNeededForExpression(context, index.Target, -1, false); Set <IStatement> parentLoops = new Set <IStatement>(); parentLoops.AddRange(targetLoops); parentLoops.AddRange(indexLoops); IVariableReferenceExpression innerIndex = (IVariableReferenceExpression)index.Indices[0]; IForStatement innerLoop = Recognizer.GetLoopForVariable(context, innerIndex); foreach (IStatement loop in parentLoops) { if (Containers.ContainersAreEqual(loop, innerLoop)) { // arrayExpr depends on i return(imie); } } IVariableDeclaration arrayVar = Recognizer.GetVariableDeclaration(arrayExpr); // If the variable is not stochastic, return if (arrayVar == null) { return(imie); } VariableInformation arrayInfo = VariableInformation.GetVariableInformation(context, arrayVar); if (!arrayInfo.IsStochastic) { return(imie); } object indexVar = Recognizer.GetDeclaration(index); VariableInformation indexInfo = VariableInformation.GetVariableInformation(context, indexVar); int depth = Recognizer.GetIndexingDepth(index); IExpression resultSize = indexInfo.sizes[depth][0]; var indices = Recognizer.GetIndices(index); int replaceCount = 0; resultSize = indexInfo.ReplaceIndexVars(context, resultSize, indices, null, ref replaceCount); indexInfo.DefineIndexVarsUpToDepth(context, depth + 1); IVariableDeclaration resultIndex = indexInfo.indexVars[depth][0]; Type arrayType = arrayExpr.GetExpressionType(); Type elementType = Util.GetElementType(arrayType); // create a new variable arrayExpr_indices = JaggedSubarray(arrayExpr, indices) string name = ToString(arrayExpr) + "_" + ToString(index.Target); var stmts = Builder.StmtCollection(); var arrayIndices = Recognizer.GetIndices(arrayExpr); var bracket = Builder.ExprCollection(); bracket.Add(Builder.ArrayIndex(index, Builder.VarRefExpr(resultIndex))); arrayIndices.Add(bracket); IExpression loopSize = Recognizer.LoopSizeExpression(innerLoop); IVariableDeclaration temp = arrayInfo.DeriveArrayVariable(stmts, context, name, resultSize, resultIndex, arrayIndices); VariableInformation tempInfo = VariableInformation.GetVariableInformation(context, temp); stmts.Clear(); IVariableDeclaration newvd = tempInfo.DeriveArrayVariable(stmts, context, name, loopSize, Recognizer.GetVariableDeclaration(innerIndex)); if (!context.InputAttributes.Has <DerivedVariable>(newvd)) { context.InputAttributes.Set(newvd, new DerivedVariable()); } IExpression rhs = Builder.StaticGenericMethod(new Func <IReadOnlyList <PlaceHolder>, int[][], PlaceHolder[][]>(Collection.JaggedSubarray), new Type[] { elementType }, arrayExpr, index.Target); context.InputAttributes.CopyObjectAttributesTo <Algorithm>(newvd, context.OutputAttributes, rhs); stmts.Add(Builder.AssignStmt(Builder.VarRefExpr(newvd), rhs)); // Reduce memory consumption by declaring the clone outside of unnecessary loops. // This way, the item is cloned outside the loop and then replicated, instead of replicating the entire array and cloning the item. Containers containers = new Containers(context); containers = RemoveReferencesTo(containers, innerIndex); containers = Containers.RemoveUnusedLoops(containers, context, rhs); if (context.InputAttributes.Has <DoNotSendEvidence>(arrayVar)) { containers = Containers.RemoveStochasticConditionals(containers, context); } // To put the declaration in the desired containers, we find an ancestor which includes as many of the containers as possible, // then wrap the declaration with the remaining containers. int ancIndex = containers.GetMatchingAncestorIndex(context); Containers missing = containers.GetContainersNotInContext(context, ancIndex); stmts = Containers.WrapWithContainers(stmts, missing.outputs); context.AddStatementsBeforeAncestorIndex(ancIndex, stmts); context.InputAttributes.Set(newvd, containers); // convert into arrayExpr_indices[i] IExpression newExpr = Builder.ArrayIndex(Builder.VarRefExpr(newvd), innerIndex); newExpr = Builder.StaticGenericMethod(new Func <PlaceHolder, PlaceHolder>(Clone.Copy <PlaceHolder>), new Type[] { newExpr.GetExpressionType() }, newExpr); return(newExpr); } } } return(imie); }