private void FixSpacingAroundKeywordFor(IForStatement item)
 {
     List<string> keywordSearch = new List<string> { "for" };
     foreach (var key in keywordSearch)
     {
         item.Text = this.whiteSpaceHelper.RemoveWhiteSpaceAroundKeyword(item.Text, key);
     }
 }
     protected override void PlaceExpression(
 IForStatement forStatement, ICSharpExpression expression, CSharpElementFactory factory)
     {
         var condition = (IRelationalExpression) forStatement.Condition;
         if (LengthPropertyName == null)
         {
           condition.RightOperand.ReplaceBy(expression);
         }
         else
         {
           var lengthAccess = factory.CreateReferenceExpression("expr.$0", LengthPropertyName);
           lengthAccess = condition.RightOperand.ReplaceBy(lengthAccess);
           lengthAccess.QualifierExpression.NotNull().ReplaceBy(expression);
         }
     }
            protected override void PlaceExpression(
        IForStatement forStatement, ICSharpExpression expression, CSharpElementFactory factory)
            {
                var variable = (ILocalVariableDeclaration)forStatement.Initializer.Declaration.Declarators[0];
                var initializer = (IExpressionInitializer)variable.Initial;

                if (LengthPropertyName == null)
                {
                  var value = initializer.Value.ReplaceBy(expression);
                  value.ReplaceBy(factory.CreateExpression("$0 - 1", value));
                }
                else
                {
                  var lengthAccess = factory.CreateReferenceExpression("expr.$0", LengthPropertyName);
                  lengthAccess = initializer.Value.ReplaceBy(lengthAccess);
                  lengthAccess.QualifierExpression.NotNull().ReplaceBy(expression);
                  lengthAccess.ReplaceBy(factory.CreateExpression("$0 - 1", lengthAccess));
                }
            }
Exemplo n.º 4
0
        private void CheckIssuesForReferencedLocalOrField(CheckCodeIssuesEventArgs ea, IForStatement loop, IElement lambda, IElement element)
        {
            if (element.ElementType == LanguageElementType.ElementReferenceExpression)
            {
                IElement declaration = element.GetDeclaration();
                if (declaration.ElementType == LanguageElementType.Variable || declaration.ElementType == LanguageElementType.InitializedVariable)
                {
                    if (loop.Initializers.Contains(declaration) || !declaration.IsParentedBy(loop))
                    {
                        ea.AddWarning(element.ToLanguageElement().Range, "Possible unintended closure scope misuse");
                    }
                }
                return;
            }

            foreach (IElement child in element.Children)
            {
                CheckIssuesForReferencedLocalOrField(ea, loop, lambda, child);
            }
        }
Exemplo n.º 5
0
 protected override IStatement ConvertFor(IForStatement ifs)
 {
     var loopSize = Recognizer.LoopSizeExpression(ifs);
     if (!((loopSize is IVariableReferenceExpression) || (loopSize is IArrayIndexerExpression) ||
           (loopSize is IArgumentReferenceExpression) || (loopSize is ILiteralExpression)
           || (loopSize is IPropertyReferenceExpression)))
     {
         Error("Invalid expression type for the size of a loop (" + loopSize.GetType().Name + "): " + loopSize);
         return ifs;
     }
     if (loopSize is ILiteralExpression ile)
     {
         // remove loops that execute for 0 iterations
         int loopSizeAsInt = (int)ile.Value;
         if (loopSizeAsInt == 0)
             return null;
     }
     Containers c = Containers.GetContainersNeededForExpression(context, loopSize);
     c.Add(ifs);
     IVariableDeclaration loopVar = Recognizer.LoopVariable(ifs);
     context.InputAttributes.Remove<Containers>(loopVar);
     context.InputAttributes.Set(loopVar, c);
     return base.ConvertFor(ifs);
 }
Exemplo n.º 6
0
        internal static void WriteDebugString(IExpression expr, IEnumerable <IStatement> containers)
        {
            string containerString = StringUtil.ToString(containers.Select(c =>
            {
                if (c is IForStatement)
                {
                    IForStatement ifs = (IForStatement)c;
                    if (c is IBrokenForStatement)
                    {
                        return(ifs.Initializer.ToString() + " // broken");
                    }
                    else
                    {
                        return(ifs.Initializer.ToString());
                    }
                }
                else
                {
                    return(((IConditionStatement)c).Condition.ToString());
                }
            }));

            Trace.WriteLine(StringUtil.JoinColumns(expr, " ", containerString));
        }
Exemplo n.º 7
0
        protected override IStatement ConvertFor(IForStatement ifs)
        {
            bool isIterationLoop = false;
            var  loopVar         = Recognizer.LoopVariable(ifs);

            if (loopVar.Name == "iteration")
            {
                iterationVar = loopVar;
                tableOfIndexVars.Clear();
                isIterationLoop = true;
            }
            IStatement ist = base.ConvertFor(ifs);

            if (isIterationLoop)
            {
                IForStatement fs = (IForStatement)ist;
                foreach (var table in tableOfIndexVars.Values)
                {
                    WriteTable(table, fs.Body.Statements);
                }
                iterationVar = null;
            }
            return(ist);
        }
Exemplo n.º 8
0
        // For the first assignment to a local variable in a block before a control statement is hit,
        // if the local variable is not mentioned previously, we turn this assignment into a local declaration.
        private void AddDeclarationsWithInitialValues(IEnumerable <ILocalDefinition> localVariables, BasicBlock block)
        {
            List <ILocalDefinition> topLevelLocals = new List <ILocalDefinition>(localVariables);
            List <ILocalDefinition> localsMet      = new List <ILocalDefinition>();

            for (int i = 0; i < block.Statements.Count; i++)
            {
                if (topLevelLocals.Count == 0)
                {
                    break;
                }
                IExpressionStatement expressionStatement = block.Statements[i] as IExpressionStatement;
                if (expressionStatement != null)
                {
                    IAssignment assignment = expressionStatement.Expression as IAssignment;
                    if (assignment != null)
                    {
                        ILocalDefinition localDef = assignment.Target.Definition as ILocalDefinition;
                        if (localDef != null && topLevelLocals.Contains(localDef) && !localsMet.Contains(localDef) && !this.declaredLocals.ContainsKey(localDef))
                        {
                            LocalDeclarationStatement localDecl = new LocalDeclarationStatement()
                            {
                                LocalVariable = localDef, InitialValue = assignment.Source, Locations = new List <ILocation>(expressionStatement.Locations),
                            };
                            this.declaredLocals.Add(localDef, true);
                            block.Statements[i] = localDecl;
                            topLevelLocals.Remove(localDef);
                            localsMet.Add(localDef);
                        }
                    }
                }
                LocalFinder finder = new LocalFinder();
                finder.Traverse(block.Statements[i]);
                foreach (ILocalDefinition local in finder.FoundLocals)
                {
                    if (!localsMet.Contains(local))
                    {
                        localsMet.Add(local);
                    }
                }
                //Once we see a statement that can transfer control somewhere else, we
                //no longer know that any subsequent assignment dominates all references
                //and hence cannot postpone adding the declaration until we can unify it with the assignment.
                IGotoStatement gotoStatement = block.Statements[i] as IGotoStatement;
                if (gotoStatement != null)
                {
                    break;
                }
                IConditionalStatement conditionalStatement = block.Statements[i] as IConditionalStatement;
                if (conditionalStatement != null)
                {
                    break;
                }
                ISwitchStatement switchStatement = block.Statements[i] as ISwitchStatement;
                if (switchStatement != null)
                {
                    break;
                }
                IForEachStatement foreachStatement = block.Statements[i] as IForEachStatement;
                if (foreachStatement != null)
                {
                    break;
                }
                IForStatement forStatement = block.Statements[i] as IForStatement;
                if (forStatement != null)
                {
                    break;
                }
                ITryCatchFinallyStatement tryStatement = block.Statements[i] as ITryCatchFinallyStatement;
                if (tryStatement != null)
                {
                    break;
                }
            }
        }
Exemplo n.º 9
0
 /// <summary>
 /// Traverses the for statement.
 /// </summary>
 public void Traverse(IForStatement forStatement)
 {
     Contract.Requires(forStatement != null);
       if (this.preorderVisitor != null) this.preorderVisitor.Visit(forStatement);
       if (this.StopTraversal) return;
       this.TraverseChildren(forStatement);
       if (this.StopTraversal) return;
       if (this.postorderVisitor != null) this.postorderVisitor.Visit(forStatement);
 }
Exemplo n.º 10
0
 void CompileForStatement(IForStatement statement)
 {
     statement.Accept(this);
 }
Exemplo n.º 11
0
 public override void VisitForStatement(IForStatement forStatement, IHighlightingConsumer consumer)
 {
     VisitLoop(forStatement, consumer);
 }
Exemplo n.º 12
0
 public virtual void onASTElement(IForStatement forStatement) { }
Exemplo n.º 13
0
        protected override IStatement ConvertFor(IForStatement ifs)
        {
            if (context.InputAttributes.Has <ConvergenceLoop>(ifs))
            {
                SerialSchedulingInfo info = context.InputAttributes.Get <SerialSchedulingInfo>(ifs);
                if (info != null)
                {
                    sequentialLoops.Clear();
                    foreach (SerialLoopInfo loopInfo in info.loopInfos)
                    {
                        sequentialLoops.Add(loopInfo.loopVar);
                    }
                }
            }
            ifs = (IForStatement)base.ConvertFor(ifs);
            // collect a list of all nested loops
            List <IForStatement> loops      = new List <IForStatement>();
            List <IForStatement> otherLoops = new List <IForStatement>();
            IForStatement        fs         = ifs;

            while (true)
            {
                IExpression loopStart = Recognizer.LoopStartExpression(fs);
                IExpression loopSize  = Recognizer.LoopSizeExpression(fs);
                containsLoopVar = false;
                ConvertExpression(loopStart);
                ConvertExpression(loopSize);
                if (!containsLoopVar)
                {
                    loops.Add(fs);
                }
                else
                {
                    otherLoops.Add(fs);
                }
                if (fs is IBrokenForStatement)
                {
                    break;
                }
                if (fs.Body.Statements.Count != 1)
                {
                    break;
                }
                if (!(fs.Body.Statements[0] is IForStatement))
                {
                    break;
                }
                fs = (IForStatement)fs.Body.Statements[0];
            }
            if (loops.Count + otherLoops.Count == 1)
            {
                return(ifs);
            }
            IList <IStatement> innermostBody = fs.Body.Statements;

            innermostBody = Containers.WrapWithContainers(innermostBody, otherLoops.ConvertAll(s => (IStatement)s));
            loops.Sort(CompareLoops);
            IStatement wrapped = Containers.WrapWithContainers(innermostBody, loops.ConvertAll(s => (IStatement)s))[0];

            context.InputAttributes.CopyObjectAttributesTo(ifs, context.OutputAttributes, wrapped);
            return(wrapped);
        }
Exemplo n.º 14
0
        protected IExpression ConvertWithReplication(IExpression expr)
        {
            IVariableDeclaration baseVar = Recognizer.GetVariableDeclaration(expr);
            // Check if this is an index local variable
            if (baseVar == null) return expr;
            // Check if the variable is stochastic
            if (!CodeRecognizer.IsStochastic(context, baseVar)) return expr;

            // Get the loop context for this variable
            LoopContext lc = context.InputAttributes.Get<LoopContext>(baseVar);
            if (lc == null)
            {
                Error("Loop context not found for '" + baseVar.Name + "'.");
                return expr;
            }

            // Get the reference loop context for this expression
            RefLoopContext rlc = lc.GetReferenceLoopContext(context);
            // If the reference is in the same loop context as the declaration, do nothing.
            if (rlc.loops.Count == 0) return expr;

            // the set of loop variables that are constant wrt the expr
            Set<IVariableDeclaration> constantLoopVars = new Set<IVariableDeclaration>();
            constantLoopVars.AddRange(lc.loopVariables);

            // collect set of all loop variable indices in the expression
            Set<int> embeddedLoopIndices = new Set<int>();
            List<IList<IExpression>> brackets = Recognizer.GetIndices(expr);
            foreach (IList<IExpression> bracket in brackets)
            {
                foreach (IExpression index in bracket)
                {
                    IExpression indExpr = index;
                    if (indExpr is IBinaryExpression ibe)
                    {
                        indExpr = ibe.Left;
                    }
                    IVariableDeclaration indVar = Recognizer.GetVariableDeclaration(indExpr);
                    if (indVar != null)
                    {
                        if (!constantLoopVars.Contains(indVar))
                        {
                            int loopIndex = rlc.loopVariables.IndexOf(indVar);
                            if (loopIndex != -1)
                            {
                                // indVar is a loop variable
                                constantLoopVars.Add(rlc.loopVariables[loopIndex]);
                            }
                            else 
                            {
                                // indVar is not a loop variable
                                LoopContext lc2 = context.InputAttributes.Get<LoopContext>(indVar);
                                foreach (var ivd in lc2.loopVariables)
                                {
                                    if (!constantLoopVars.Contains(ivd))
                                    {
                                        int loopIndex2 = rlc.loopVariables.IndexOf(ivd);
                                        if (loopIndex2 != -1)
                                            embeddedLoopIndices.Add(loopIndex2);
                                        else
                                            Error($"Index {ivd} is not in {rlc} for expression {expr}");
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        foreach(var ivd in Recognizer.GetVariables(indExpr))
                        {
                            if (!constantLoopVars.Contains(ivd))
                            {
                                // copied from above
                                LoopContext lc2 = context.InputAttributes.Get<LoopContext>(ivd);
                                foreach (var ivd2 in lc2.loopVariables)
                                {
                                    if (!constantLoopVars.Contains(ivd2))
                                    {
                                        int loopIndex2 = rlc.loopVariables.IndexOf(ivd2);
                                        if (loopIndex2 != -1)
                                            embeddedLoopIndices.Add(loopIndex2);
                                        else
                                            Error($"Index {ivd2} is not in {rlc} for expression {expr}");
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // Find loop variables that must be constant due to condition statements.
            List<IStatement> ancestors = context.FindAncestors<IStatement>();
            foreach (IStatement ancestor in ancestors)
            {
                if (!(ancestor is IConditionStatement ics))
                    continue;
                ConditionBinding binding = new ConditionBinding(ics.Condition);
                IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(binding.lhs);
                IVariableDeclaration ivd2 = Recognizer.GetVariableDeclaration(binding.rhs);
                int index = rlc.loopVariables.IndexOf(ivd);
                if (index >= 0 && IsConstantWrtLoops(ivd2, constantLoopVars))
                {
                    constantLoopVars.Add(ivd);
                    continue;
                }
                int index2 = rlc.loopVariables.IndexOf(ivd2);
                if (index2 >= 0 && IsConstantWrtLoops(ivd, constantLoopVars))
                {
                    constantLoopVars.Add(ivd2);
                    continue;
                }
            }

            // Determine if this expression is being defined (is on the LHS of an assignment)
            bool isDef = Recognizer.IsBeingMutated(context, expr);

            Containers containers = context.InputAttributes.Get<Containers>(baseVar);

            IExpression originalExpr = expr;

            for (int currentLoop = 0; currentLoop < rlc.loopVariables.Count; currentLoop++)
            {
                IVariableDeclaration loopVar = rlc.loopVariables[currentLoop];
                if (constantLoopVars.Contains(loopVar))
                    continue;
                IForStatement loop = rlc.loops[currentLoop];
                // must replicate across this loop.
                if (isDef)
                {
                    Error("Cannot re-define a variable in a loop.  Variables on the left hand side of an assignment must be indexed by all containing loops.");
                    continue;
                }
                if (embeddedLoopIndices.Contains(currentLoop))
                {
                    string warningText = "This model will consume excess memory due to the indexing expression {0} inside of a loop over {1}. Try simplifying this expression in your model, perhaps by creating auxiliary index arrays.";
                    Warning(string.Format(warningText, originalExpr, loopVar.Name));
                }
                // split expr into a target and extra indices, where target will be replicated and extra indices will be added later
                var extraIndices = new List<IEnumerable<IExpression>>();
                AddUnreplicatedIndices(rlc.loops[currentLoop], expr, extraIndices, out IExpression exprToReplicate);

                VariableInformation varInfo = VariableInformation.GetVariableInformation(context, baseVar);
                IExpression loopSize = Recognizer.LoopSizeExpression(loop);
                IList<IStatement> stmts = Builder.StmtCollection();
                List<IList<IExpression>> inds = Recognizer.GetIndices(exprToReplicate);
                IVariableDeclaration newIndexVar = loopVar;
                // if loopVar is already an indexVar of varInfo, create a new variable
                if (varInfo.HasIndexVar(loopVar))
                {
                    newIndexVar = VariableInformation.GenerateLoopVar(context, "_a");
                    context.InputAttributes.CopyObjectAttributesTo(loopVar, context.OutputAttributes, newIndexVar);
                }
                IVariableDeclaration repVar = varInfo.DeriveArrayVariable(stmts, context, VariableInformation.GenerateName(context, varInfo.Name + "_rep"),
                                                                          loopSize, newIndexVar, inds, useArrays: true);
                if (!context.InputAttributes.Has<DerivedVariable>(repVar))
                    context.OutputAttributes.Set(repVar, new DerivedVariable());
                if (context.InputAttributes.Has<ChannelInfo>(baseVar))
                {
                    VariableInformation repVarInfo = VariableInformation.GetVariableInformation(context, repVar);
                    ChannelInfo ci = ChannelInfo.UseChannel(repVarInfo);
                    ci.decl = repVar;
                    context.OutputAttributes.Set(repVar, ci);
                }

                // Create replicate factor
                Type returnType = Builder.ToType(repVar.VariableType);
                IMethodInvokeExpression repMethod = Builder.StaticGenericMethod(
                    new Func<PlaceHolder, int, PlaceHolder[]>(Clone.Replicate),
                    new Type[] {returnType.GetElementType()}, exprToReplicate, loopSize);

                IExpression assignExpression = Builder.AssignExpr(Builder.VarRefExpr(repVar), repMethod);
                // Copy attributes across from variable to replication expression
                context.InputAttributes.CopyObjectAttributesTo<Algorithm>(baseVar, context.OutputAttributes, repMethod);
                context.InputAttributes.CopyObjectAttributesTo<DivideMessages>(baseVar, context.OutputAttributes, repMethod);
                context.InputAttributes.CopyObjectAttributesTo<GivePriorityTo>(baseVar, context.OutputAttributes, repMethod);
                stmts.Add(Builder.ExprStatement(assignExpression));

                // add any containers missing from context.
                containers = new Containers(context);
                // RemoveUnusedLoops will also remove conditionals involving those loop variables.
                // TODO: investigate whether removing these conditionals could cause a problem, e.g. when the condition is a conjunction of many terms.
                containers = Containers.RemoveUnusedLoops(containers, context, repMethod);
                if (context.InputAttributes.Has<DoNotSendEvidence>(baseVar)) containers = Containers.RemoveStochasticConditionals(containers, context);
                //Containers shouldBeEmpty = containers.GetContainersNotInContext(context, context.InputStack.Count);
                //if (shouldBeEmpty.inputs.Count > 0) { Error("Internal: Variable is out of scope"); return expr; }
                if (containers.Contains(loop))
                {
                    Error("Internal: invalid containers for replicating " + baseVar);
                    break;
                }
                int ancIndex = containers.GetMatchingAncestorIndex(context);
                Containers missing = containers.GetContainersNotInContext(context, ancIndex);
                stmts = Containers.WrapWithContainers(stmts, missing.inputs);
                context.OutputAttributes.Set(repVar, containers);
                List<IForStatement> loops = context.FindAncestors<IForStatement>(ancIndex);
                foreach (IStatement container in missing.inputs)
                {
                    if (container is IForStatement ifs) loops.Add(ifs);
                }
                context.OutputAttributes.Set(repVar, new LoopContext(loops));
                // must convert the output since it may contain 'if' conditions
                context.AddStatementsBeforeAncestorIndex(ancIndex, stmts, true);
                baseVar = repVar;
                expr = Builder.ArrayIndex(Builder.VarRefExpr(repVar), Builder.VarRefExpr(loopVar));
                expr = Builder.JaggedArrayIndex(expr, extraIndices);
            }

            return expr;
        }
Exemplo n.º 15
0
        /// <summary>
        /// This method does all the work of converting literal indexing expressions.
        /// </summary>
        /// <param name="iaie"></param>
        /// <returns></returns>
        protected override IExpression ConvertArrayIndexer(IArrayIndexerExpression iaie)
        {
            IndexAnalysisTransform.IndexInfo info;
            if (!analysis.indexInfoOf.TryGetValue(iaie, out info))
            {
                return(base.ConvertArrayIndexer(iaie));
            }
            // Determine if this is a definition i.e. the variable is on the left hand side of an assignment
            // This must be done before base.ConvertArrayIndexer changes the expression!
            bool isDef = Recognizer.IsBeingMutated(context, iaie);

            if (info.clone != null)
            {
                if (isDef)
                {
                    // check that extra literal indices in the target are zero.
                    // for example, if iae is x[i][0] = (...) then it is safe to add x_uses[i] = Rep(x[i])
                    // if iae is x[i][1] = (...) then it is safe to add x_uses[i][1] = Rep(x[i][1])
                    // but not x_uses[i] = Rep(x[i]) since this will be a duplicate.
                    bool   extraLiteralsAreZero = true;
                    int    parentIndex          = context.InputStack.Count - 2;
                    object parent = context.GetAncestor(parentIndex);
                    while (parent is IArrayIndexerExpression)
                    {
                        IArrayIndexerExpression parent_iaie = (IArrayIndexerExpression)parent;
                        foreach (IExpression index in parent_iaie.Indices)
                        {
                            if (index is ILiteralExpression)
                            {
                                int value = (int)((ILiteralExpression)index).Value;
                                if (value != 0)
                                {
                                    extraLiteralsAreZero = false;
                                    break;
                                }
                            }
                        }
                        parentIndex--;
                        parent = context.GetAncestor(parentIndex);
                    }
                    if (false && extraLiteralsAreZero)
                    {
                        // change:
                        //   array[0] = f()
                        // into:
                        //   array_item0 = f()
                        //   array[0] = Copy(array_item0)
                        IExpression copy = Builder.StaticGenericMethod(new Func <PlaceHolder, PlaceHolder>(Clone.Copy <PlaceHolder>), new Type[] { iaie.GetExpressionType() },
                                                                       info.clone);
                        IStatement copySt = Builder.AssignStmt(iaie, copy);
                        context.AddStatementAfterCurrent(copySt);
                    }
                }
                return(info.clone);
            }

            if (isDef)
            {
                // do not clone the lhs of an array create assignment.
                IAssignExpression assignExpr = context.FindAncestor <IAssignExpression>();
                if (assignExpr.Expression is IArrayCreateExpression)
                {
                    return(iaie);
                }
            }

            IVariableDeclaration originalBaseVar = Recognizer.GetVariableDeclaration(iaie);

            // If the variable is not stochastic, return
            if (!CodeRecognizer.IsStochastic(context, originalBaseVar))
            {
                return(iaie);
            }

            IExpression          newExpr    = null;
            IVariableDeclaration baseVar    = originalBaseVar;
            IVariableDeclaration newvd      = null;
            IExpression          rhsExpr    = null;
            Containers           containers = info.containers;
            Type tp = iaie.GetExpressionType();

            if (tp == null)
            {
                Error("Could not determine type of expression: " + iaie);
                return(iaie);
            }
            var stmts      = Builder.StmtCollection();
            var stmtsAfter = Builder.StmtCollection();

            // does the expression have the form array[indices[k]][indices2[k]][indices3[k]]?
            if (newvd == null && UseGetItems && iaie.Target is IArrayIndexerExpression &&
                iaie.Indices.Count == 1 && iaie.Indices[0] is IArrayIndexerExpression)
            {
                IArrayIndexerExpression index3 = (IArrayIndexerExpression)iaie.Indices[0];
                IArrayIndexerExpression iaie2  = (IArrayIndexerExpression)iaie.Target;
                if (index3.Indices.Count == 1 && index3.Indices[0] is IVariableReferenceExpression &&
                    iaie2.Target is IArrayIndexerExpression &&
                    iaie2.Indices.Count == 1 && iaie2.Indices[0] is IArrayIndexerExpression)
                {
                    IArrayIndexerExpression index2 = (IArrayIndexerExpression)iaie2.Indices[0];
                    IArrayIndexerExpression iaie3  = (IArrayIndexerExpression)iaie2.Target;
                    if (index2.Indices.Count == 1 && index2.Indices[0] is IVariableReferenceExpression &&
                        iaie3.Indices.Count == 1 && iaie3.Indices[0] is IArrayIndexerExpression)
                    {
                        IArrayIndexerExpression      index      = (IArrayIndexerExpression)iaie3.Indices[0];
                        IVariableReferenceExpression innerIndex = (IVariableReferenceExpression)index.Indices[0];
                        IForStatement innerLoop = Recognizer.GetLoopForVariable(context, innerIndex);
                        if (index.Indices.Count == 1 && index2.Indices[0].Equals(innerIndex) &&
                            index3.Indices[0].Equals(innerIndex) &&
                            innerLoop != null && AreLoopsDisjoint(innerLoop, iaie3.Target, index.Target))
                        {
                            // expression has the form array[indices[k]][indices2[k]][indices3[k]]
                            if (isDef)
                            {
                                Error("fancy indexing not allowed on left hand side");
                                return(iaie);
                            }
                            WarnIfLocal(index.Target, iaie3.Target, iaie);
                            WarnIfLocal(index2.Target, iaie3.Target, iaie);
                            WarnIfLocal(index3.Target, iaie3.Target, iaie);
                            containers = RemoveReferencesTo(containers, innerIndex);
                            IExpression loopSize = Recognizer.LoopSizeExpression(innerLoop);
                            var         indices  = Recognizer.GetIndices(iaie);
                            // Build name of replacement variable from index values
                            StringBuilder sb = new StringBuilder("_item");
                            AppendIndexString(sb, iaie3);
                            AppendIndexString(sb, iaie2);
                            AppendIndexString(sb, iaie);
                            string name = ToString(iaie3.Target) + sb.ToString();
                            VariableInformation varInfo = VariableInformation.GetVariableInformation(context, baseVar);
                            newvd = varInfo.DeriveArrayVariable(stmts, context, name, loopSize, Recognizer.GetVariableDeclaration(innerIndex), indices);
                            if (!context.InputAttributes.Has <DerivedVariable>(newvd))
                            {
                                context.InputAttributes.Set(newvd, new DerivedVariable());
                            }
                            IExpression getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <IReadOnlyList <IReadOnlyList <PlaceHolder> > >, IReadOnlyList <int>, IReadOnlyList <int>, IReadOnlyList <int>, PlaceHolder[]>(Collection.GetItemsFromDeepJagged),
                                                                               new Type[] { tp }, iaie3.Target, index.Target, index2.Target, index3.Target);
                            context.InputAttributes.CopyObjectAttributesTo <Algorithm>(baseVar, context.OutputAttributes, getItems);
                            stmts.Add(Builder.AssignStmt(Builder.VarRefExpr(newvd), getItems));
                            newExpr = Builder.ArrayIndex(Builder.VarRefExpr(newvd), innerIndex);
                            rhsExpr = getItems;
                        }
                    }
                }
            }
            // does the expression have the form array[indices[k]][indices2[k]]?
            if (newvd == null && UseGetItems && iaie.Target is IArrayIndexerExpression &&
                iaie.Indices.Count == 1 && iaie.Indices[0] is IArrayIndexerExpression)
            {
                IArrayIndexerExpression index2 = (IArrayIndexerExpression)iaie.Indices[0];
                IArrayIndexerExpression target = (IArrayIndexerExpression)iaie.Target;
                if (index2.Indices.Count == 1 && index2.Indices[0] is IVariableReferenceExpression &&
                    target.Indices.Count == 1 && target.Indices[0] is IArrayIndexerExpression)
                {
                    IVariableReferenceExpression innerIndex = (IVariableReferenceExpression)index2.Indices[0];
                    IArrayIndexerExpression      index      = (IArrayIndexerExpression)target.Indices[0];
                    IForStatement innerLoop = Recognizer.GetLoopForVariable(context, innerIndex);
                    if (index.Indices.Count == 1 && index.Indices[0].Equals(innerIndex) &&
                        innerLoop != null && AreLoopsDisjoint(innerLoop, target.Target, index.Target))
                    {
                        // expression has the form array[indices[k]][indices2[k]]
                        if (isDef)
                        {
                            Error("fancy indexing not allowed on left hand side");
                            return(iaie);
                        }
                        var innerLoops = new List <IForStatement>();
                        innerLoops.Add(innerLoop);
                        var indexTarget  = index.Target;
                        var index2Target = index2.Target;
                        // check if the index array is jagged, i.e. array[indices[k][j]]
                        while (indexTarget is IArrayIndexerExpression && index2Target is IArrayIndexerExpression)
                        {
                            IArrayIndexerExpression indexTargetExpr  = (IArrayIndexerExpression)indexTarget;
                            IArrayIndexerExpression index2TargetExpr = (IArrayIndexerExpression)index2Target;
                            if (indexTargetExpr.Indices.Count == 1 && indexTargetExpr.Indices[0] is IVariableReferenceExpression &&
                                index2TargetExpr.Indices.Count == 1 && index2TargetExpr.Indices[0] is IVariableReferenceExpression)
                            {
                                IVariableReferenceExpression innerIndexTarget  = (IVariableReferenceExpression)indexTargetExpr.Indices[0];
                                IVariableReferenceExpression innerIndex2Target = (IVariableReferenceExpression)index2TargetExpr.Indices[0];
                                IForStatement indexTargetLoop = Recognizer.GetLoopForVariable(context, innerIndexTarget);
                                if (indexTargetLoop != null && AreLoopsDisjoint(indexTargetLoop, target.Target, indexTargetExpr.Target) &&
                                    innerIndexTarget.Equals(innerIndex2Target))
                                {
                                    innerLoops.Add(indexTargetLoop);
                                    indexTarget  = indexTargetExpr.Target;
                                    index2Target = index2TargetExpr.Target;
                                }
                                else
                                {
                                    break;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                        WarnIfLocal(indexTarget, target.Target, iaie);
                        WarnIfLocal(index2Target, target.Target, iaie);
                        innerLoops.Reverse();
                        var loopSizes    = innerLoops.ListSelect(ifs => new[] { Recognizer.LoopSizeExpression(ifs) });
                        var newIndexVars = innerLoops.ListSelect(ifs => new[] { Recognizer.LoopVariable(ifs) });
                        // Build name of replacement variable from index values
                        StringBuilder sb = new StringBuilder("_item");
                        AppendIndexString(sb, target);
                        AppendIndexString(sb, iaie);
                        string name = ToString(target.Target) + sb.ToString();
                        VariableInformation varInfo = VariableInformation.GetVariableInformation(context, baseVar);
                        var indices = Recognizer.GetIndices(iaie);
                        newvd = varInfo.DeriveArrayVariable(stmts, context, name, loopSizes, newIndexVars, indices);
                        if (!context.InputAttributes.Has <DerivedVariable>(newvd))
                        {
                            context.InputAttributes.Set(newvd, new DerivedVariable());
                        }
                        IExpression getItems;
                        if (innerLoops.Count == 1)
                        {
                            getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <IReadOnlyList <PlaceHolder> >, IReadOnlyList <int>, IReadOnlyList <int>, PlaceHolder[]>(Collection.GetItemsFromJagged),
                                                                   new Type[] { tp }, target.Target, indexTarget, index2Target);
                        }
                        else if (innerLoops.Count == 2)
                        {
                            getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <IReadOnlyList <PlaceHolder> >, IReadOnlyList <IReadOnlyList <int> >, IReadOnlyList <IReadOnlyList <int> >, PlaceHolder[][]>(Collection.GetJaggedItemsFromJagged),
                                                                   new Type[] { tp }, target.Target, indexTarget, index2Target);
                        }
                        else
                        {
                            throw new NotImplementedException($"innerLoops.Count = {innerLoops.Count}");
                        }
                        context.InputAttributes.CopyObjectAttributesTo <Algorithm>(baseVar, context.OutputAttributes, getItems);
                        stmts.Add(Builder.AssignStmt(Builder.VarRefExpr(newvd), getItems));
                        var newIndices = newIndexVars.ListSelect(ivds => Util.ArrayInit(ivds.Length, i => Builder.VarRefExpr(ivds[i])));
                        newExpr = Builder.JaggedArrayIndex(Builder.VarRefExpr(newvd), newIndices);
                        rhsExpr = getItems;
                    }
                    else if (HasAnyCommonLoops(index, index2))
                    {
                        Warning($"This model will consume excess memory due to the indexing expression {iaie} since {index} and {index2} have larger depth than the compiler can handle.");
                    }
                }
            }
            if (newvd == null)
            {
                IArrayIndexerExpression originalExpr = iaie;
                if (UseGetItems)
                {
                    iaie = (IArrayIndexerExpression)base.ConvertArrayIndexer(iaie);
                }
                if (!object.ReferenceEquals(iaie.Target, originalExpr.Target) && false)
                {
                    // TODO: determine if this warning is useful or not
                    string warningText = "This model may consume excess memory due to the jagged indexing expression {0}";
                    Warning(string.Format(warningText, originalExpr));
                }

                // get the baseVar of the new expression.
                baseVar = Recognizer.GetVariableDeclaration(iaie);
                VariableInformation varInfo = VariableInformation.GetVariableInformation(context, baseVar);

                var indices = Recognizer.GetIndices(iaie);
                // Build name of replacement variable from index values
                StringBuilder sb = new StringBuilder("_item");
                AppendIndexString(sb, iaie);
                string name = ToString(iaie.Target) + sb.ToString();

                // does the expression have the form array[indices[k]]?
                if (UseGetItems && iaie.Indices.Count == 1 && iaie.Indices[0] is IArrayIndexerExpression)
                {
                    IArrayIndexerExpression index = (IArrayIndexerExpression)iaie.Indices[0];
                    if (index.Indices.Count == 1 && index.Indices[0] is IVariableReferenceExpression)
                    {
                        // expression has the form array[indices[k]]
                        IVariableReferenceExpression innerIndex = (IVariableReferenceExpression)index.Indices[0];
                        IForStatement innerLoop = Recognizer.GetLoopForVariable(context, innerIndex);
                        if (innerLoop != null && AreLoopsDisjoint(innerLoop, iaie.Target, index.Target))
                        {
                            if (isDef)
                            {
                                Error("fancy indexing not allowed on left hand side");
                                return(iaie);
                            }
                            var innerLoops = new List <IForStatement>();
                            innerLoops.Add(innerLoop);
                            var indexTarget = index.Target;
                            // check if the index array is jagged, i.e. array[indices[k][j]]
                            while (indexTarget is IArrayIndexerExpression)
                            {
                                IArrayIndexerExpression index2 = (IArrayIndexerExpression)indexTarget;
                                if (index2.Indices.Count == 1 && index2.Indices[0] is IVariableReferenceExpression)
                                {
                                    IVariableReferenceExpression innerIndex2 = (IVariableReferenceExpression)index2.Indices[0];
                                    IForStatement innerLoop2 = Recognizer.GetLoopForVariable(context, innerIndex2);
                                    if (innerLoop2 != null && AreLoopsDisjoint(innerLoop2, iaie.Target, index2.Target))
                                    {
                                        innerLoops.Add(innerLoop2);
                                        indexTarget = index2.Target;
                                        // This limit must match the number of handled cases below.
                                        if (innerLoops.Count == 3)
                                        {
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
                            WarnIfLocal(indexTarget, iaie.Target, originalExpr);
                            innerLoops.Reverse();
                            var loopSizes    = innerLoops.ListSelect(ifs => new[] { Recognizer.LoopSizeExpression(ifs) });
                            var newIndexVars = innerLoops.ListSelect(ifs => new[] { Recognizer.LoopVariable(ifs) });
                            newvd = varInfo.DeriveArrayVariable(stmts, context, name, loopSizes, newIndexVars, indices);
                            if (!context.InputAttributes.Has <DerivedVariable>(newvd))
                            {
                                context.InputAttributes.Set(newvd, new DerivedVariable());
                            }
                            IExpression getItems;
                            if (innerLoops.Count == 1)
                            {
                                getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <PlaceHolder>, IReadOnlyList <int>, PlaceHolder[]>(Collection.GetItems),
                                                                       new Type[] { tp }, iaie.Target, indexTarget);
                            }
                            else if (innerLoops.Count == 2)
                            {
                                getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <PlaceHolder>, IReadOnlyList <IReadOnlyList <int> >, PlaceHolder[][]>(Collection.GetJaggedItems),
                                                                       new Type[] { tp }, iaie.Target, indexTarget);
                            }
                            else if (innerLoops.Count == 3)
                            {
                                getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <PlaceHolder>, IReadOnlyList <IReadOnlyList <IReadOnlyList <int> > >, PlaceHolder[][][]>(Collection.GetDeepJaggedItems),
                                                                       new Type[] { tp }, iaie.Target, indexTarget);
                            }
                            else
                            {
                                throw new NotImplementedException($"innerLoops.Count = {innerLoops.Count}");
                            }
                            context.InputAttributes.CopyObjectAttributesTo <Algorithm>(baseVar, context.OutputAttributes, getItems);
                            stmts.Add(Builder.AssignStmt(Builder.VarRefExpr(newvd), getItems));
                            var newIndices = newIndexVars.ListSelect(ivds => Util.ArrayInit(ivds.Length, i => Builder.VarRefExpr(ivds[i])));
                            newExpr = Builder.JaggedArrayIndex(Builder.VarRefExpr(newvd), newIndices);
                            rhsExpr = getItems;
                        }
                    }
                }
                if (newvd == null)
                {
                    if (UseGetItems && info.count < 2)
                    {
                        return(iaie);
                    }
                    try
                    {
                        newvd = varInfo.DeriveIndexedVariable(stmts, context, name, indices, copyInitializer: isDef);
                    }
                    catch (Exception ex)
                    {
                        Error(ex.Message, ex);
                        return(iaie);
                    }
                    context.OutputAttributes.Remove <DerivedVariable>(newvd);
                    newExpr = Builder.VarRefExpr(newvd);
                    rhsExpr = iaie;
                    if (isDef)
                    {
                        // change:
                        //   array[0] = f()
                        // into:
                        //   array_item0 = f()
                        //   array[0] = Copy(array_item0)
                        IExpression copy   = Builder.StaticGenericMethod(new Func <PlaceHolder, PlaceHolder>(Clone.Copy), new Type[] { tp }, newExpr);
                        IStatement  copySt = Builder.AssignStmt(iaie, copy);
                        stmtsAfter.Add(copySt);
                        if (!context.InputAttributes.Has <DerivedVariable>(baseVar))
                        {
                            context.InputAttributes.Set(baseVar, new DerivedVariable());
                        }
                    }
                    else if (!info.IsAssignedTo)
                    {
                        // change:
                        //   x = f(array[0])
                        // into:
                        //   array_item0 = Copy(array[0])
                        //   x = f(array_item0)
                        IExpression copy   = Builder.StaticGenericMethod(new Func <PlaceHolder, PlaceHolder>(Clone.Copy), new Type[] { tp }, iaie);
                        IStatement  copySt = Builder.AssignStmt(Builder.VarRefExpr(newvd), copy);
                        //if (attr != null) context.OutputAttributes.Set(copySt, attr);
                        stmts.Add(copySt);
                        context.InputAttributes.Set(newvd, new DerivedVariable());
                    }
                }
            }

            // 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.RemoveUnusedLoops(containers, context, rhsExpr);
            if (context.InputAttributes.Has <DoNotSendEvidence>(originalBaseVar))
            {
                containers = Containers.RemoveStochasticConditionals(containers, context);
            }
            if (true)
            {
                IStatement st = GetBindingSetContainer(FilterBindingSet(info.bindings,
                                                                        binding => Containers.ContainsExpression(containers.inputs, context, binding.GetExpression())));
                if (st != null)
                {
                    containers.Add(st);
                }
            }
            // 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);
            stmtsAfter = Containers.WrapWithContainers(stmtsAfter, missing.outputs);
            context.AddStatementsAfterAncestorIndex(ancIndex, stmtsAfter);
            context.InputAttributes.Set(newvd, containers);
            info.clone = newExpr;
            return(newExpr);
        }
Exemplo n.º 16
0
 public override void VisitForStatement <TExpression, TForInitializerStatement, TStatement>(IForStatement <TExpression, TForInitializerStatement, TStatement> forStatement)
 {
     Value = new Statement()
     {
         ForStatement = new ForStatementFactory(forStatement).Value
     };
 }
Exemplo n.º 17
0
 public void Visit(IForStatement forStatement)
 {
     this.traverser.Traverse(forStatement);
 }
Exemplo n.º 18
0
 public override void Visit(IForStatement forStatement)
 {
     allElements.Add(new InvokInfo(Traverser, "IForStatement", forStatement));
 }
Exemplo n.º 19
0
        /// <summary>
        /// Generates IL for the specified for statement.
        /// </summary>
        /// <param name="forStatement">For statement.</param>
        public override void TraverseChildren(IForStatement forStatement)
        {
            ILGeneratorLabel savedCurrentBreakTarget = this.currentBreakTarget;
              ILGeneratorLabel savedCurrentContinueTarget = this.currentContinueTarget;
              this.currentBreakTarget = new ILGeneratorLabel();
              this.currentContinueTarget = new ILGeneratorLabel();
              if (this.currentTryCatch != null) {
            this.mostNestedTryCatchFor.Add(this.currentBreakTarget, this.currentTryCatch);
            this.mostNestedTryCatchFor.Add(this.currentContinueTarget, this.currentTryCatch);
              }
              ILGeneratorLabel conditionCheck = new ILGeneratorLabel();
              ILGeneratorLabel loopStart = new ILGeneratorLabel();

              this.Traverse(forStatement.InitStatements);
              this.generator.Emit(OperationCode.Br, conditionCheck);
              this.generator.MarkLabel(loopStart);
              this.Traverse(forStatement.Body);
              this.generator.MarkLabel(this.currentContinueTarget);
              this.Traverse(forStatement.IncrementStatements);
              this.generator.MarkLabel(conditionCheck);
              this.EmitSequencePoint(forStatement.Condition.Locations);
              this.VisitBranchIfTrue(forStatement.Condition, loopStart);
              this.generator.MarkLabel(this.currentBreakTarget);

              this.currentBreakTarget = savedCurrentBreakTarget;
              this.currentContinueTarget = savedCurrentContinueTarget;
              this.lastStatementWasUnconditionalTransfer = false;
        }
Exemplo n.º 20
0
        /// <summary>
        /// This method does all the work of converting literal indexing expressions.
        /// </summary>
        /// <param name="iaie"></param>
        /// <returns></returns>
        protected override IExpression ConvertArrayIndexer(IArrayIndexerExpression iaie)
        {
            IndexAnalysisTransform.IndexInfo info;
            if (!analysis.indexInfoOf.TryGetValue(iaie, out info))
            {
                return(base.ConvertArrayIndexer(iaie));
            }
            // Determine if this is a definition i.e. the variable is on the left hand side of an assignment
            // This must be done before base.ConvertArrayIndexer changes the expression!
            bool isDef = Recognizer.IsBeingMutated(context, iaie);

            if (info.clone != null)
            {
                if (isDef)
                {
                    // check that extra literal indices in the target are zero.
                    // for example, if iae is x[i][0] = (...) then it is safe to add x_uses[i] = Rep(x[i])
                    // if iae is x[i][1] = (...) then it is safe to add x_uses[i][1] = Rep(x[i][1])
                    // but not x_uses[i] = Rep(x[i]) since this will be a duplicate.
                    bool   extraLiteralsAreZero = true;
                    int    parentIndex          = context.InputStack.Count - 2;
                    object parent = context.GetAncestor(parentIndex);
                    while (parent is IArrayIndexerExpression parent_iaie)
                    {
                        foreach (IExpression index in parent_iaie.Indices)
                        {
                            if (index is ILiteralExpression ile)
                            {
                                int value = (int)ile.Value;
                                if (value != 0)
                                {
                                    extraLiteralsAreZero = false;
                                    break;
                                }
                            }
                        }
                        parentIndex--;
                        parent = context.GetAncestor(parentIndex);
                    }
                    if (false && extraLiteralsAreZero)
                    {
                        // change:
                        //   array[0] = f()
                        // into:
                        //   array_item0 = f()
                        //   array[0] = Copy(array_item0)
                        IExpression copy = Builder.StaticGenericMethod(new Func <PlaceHolder, PlaceHolder>(Clone.Copy <PlaceHolder>), new Type[] { iaie.GetExpressionType() },
                                                                       info.clone);
                        IStatement copySt = Builder.AssignStmt(iaie, copy);
                        context.AddStatementAfterCurrent(copySt);
                    }
                }
                return(info.clone);
            }

            if (isDef)
            {
                // do not clone the lhs of an array create assignment.
                IAssignExpression assignExpr = context.FindAncestor <IAssignExpression>();
                if (assignExpr.Expression is IArrayCreateExpression)
                {
                    return(iaie);
                }
            }

            IVariableDeclaration originalBaseVar = Recognizer.GetVariableDeclaration(iaie);

            // If the variable is not stochastic, return
            if (!CodeRecognizer.IsStochastic(context, originalBaseVar))
            {
                return(iaie);
            }

            IExpression          newExpr    = null;
            IVariableDeclaration baseVar    = originalBaseVar;
            IVariableDeclaration newvd      = null;
            IExpression          rhsExpr    = null;
            Containers           containers = info.containers;
            Type tp = iaie.GetExpressionType();

            if (tp == null)
            {
                Error("Could not determine type of expression: " + iaie);
                return(iaie);
            }
            var stmts      = Builder.StmtCollection();
            var stmtsAfter = Builder.StmtCollection();

            // does the expression have the form array[indices[k]][indices2[k]][indices3[k]]?
            if (newvd == null && UseGetItems && iaie.Indices.Count == 1)
            {
                if (iaie.Target is IArrayIndexerExpression iaie2 &&
                    iaie.Indices[0] is IArrayIndexerExpression index3 &&
                    index3.Indices.Count == 1 &&
                    index3.Indices[0] is IVariableReferenceExpression innerIndex3 &&
                    iaie2.Target is IArrayIndexerExpression iaie3 &&
                    iaie2.Indices.Count == 1 &&
                    iaie2.Indices[0] is IArrayIndexerExpression index2 &&
                    index2.Indices.Count == 1 &&
                    index2.Indices[0] is IVariableReferenceExpression innerIndex2 &&
                    innerIndex2.Equals(innerIndex3) &&
                    iaie3.Indices.Count == 1 &&
                    iaie3.Indices[0] is IArrayIndexerExpression index &&
                    index.Indices.Count == 1 &&
                    index.Indices[0] is IVariableReferenceExpression innerIndex &&
                    innerIndex.Equals(innerIndex2))
                {
                    IForStatement innerLoop = Recognizer.GetLoopForVariable(context, innerIndex);
                    if (innerLoop != null &&
                        AreLoopsDisjoint(innerLoop, iaie3.Target, index.Target))
                    {
                        // expression has the form array[indices[k]][indices2[k]][indices3[k]]
                        if (isDef)
                        {
                            Error("fancy indexing not allowed on left hand side");
                            return(iaie);
                        }
                        WarnIfLocal(index.Target, iaie3.Target, iaie);
                        WarnIfLocal(index2.Target, iaie3.Target, iaie);
                        WarnIfLocal(index3.Target, iaie3.Target, iaie);
                        containers = RemoveReferencesTo(containers, innerIndex);
                        IExpression loopSize = Recognizer.LoopSizeExpression(innerLoop);
                        var         indices  = Recognizer.GetIndices(iaie);
                        // Build name of replacement variable from index values
                        StringBuilder sb = new StringBuilder("_item");
                        AppendIndexString(sb, iaie3);
                        AppendIndexString(sb, iaie2);
                        AppendIndexString(sb, iaie);
                        string name = ToString(iaie3.Target) + sb.ToString();
                        VariableInformation varInfo = VariableInformation.GetVariableInformation(context, baseVar);
                        newvd = varInfo.DeriveArrayVariable(stmts, context, name, loopSize, Recognizer.GetVariableDeclaration(innerIndex), indices);
                        if (!context.InputAttributes.Has <DerivedVariable>(newvd))
                        {
                            context.InputAttributes.Set(newvd, new DerivedVariable());
                        }
                        IExpression getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <IReadOnlyList <IReadOnlyList <PlaceHolder> > >, IReadOnlyList <int>, IReadOnlyList <int>, IReadOnlyList <int>, PlaceHolder[]>(Collection.GetItemsFromDeepJagged),
                                                                           new Type[] { tp }, iaie3.Target, index.Target, index2.Target, index3.Target);
                        context.InputAttributes.CopyObjectAttributesTo <Algorithm>(baseVar, context.OutputAttributes, getItems);
                        stmts.Add(Builder.AssignStmt(Builder.VarRefExpr(newvd), getItems));
                        newExpr = Builder.ArrayIndex(Builder.VarRefExpr(newvd), innerIndex);
                        rhsExpr = getItems;
                    }
                }
            }
            // does the expression have the form array[indices[k]][indices2[k]]?
            if (newvd == null && UseGetItems && iaie.Indices.Count == 1)
            {
                if (iaie.Target is IArrayIndexerExpression target &&
                    iaie.Indices[0] is IArrayIndexerExpression index2 &&
                    index2.Indices.Count == 1 &&
                    index2.Indices[0] is IVariableReferenceExpression innerIndex &&
                    target.Indices.Count == 1 &&
                    target.Indices[0] is IArrayIndexerExpression index)
                {
                    IForStatement innerLoop = Recognizer.GetLoopForVariable(context, innerIndex);
                    if (index.Indices.Count == 1 &&
                        index.Indices[0].Equals(innerIndex) &&
                        innerLoop != null &&
                        AreLoopsDisjoint(innerLoop, target.Target, index.Target))
                    {
                        // expression has the form array[indices[k]][indices2[k]]
                        if (isDef)
                        {
                            Error("fancy indexing not allowed on left hand side");
                            return(iaie);
                        }
                        var innerLoops = new List <IForStatement>();
                        innerLoops.Add(innerLoop);
                        var indexTarget  = index.Target;
                        var index2Target = index2.Target;
                        // check if the index array is jagged, i.e. array[indices[k][j]]
                        while (indexTarget is IArrayIndexerExpression indexTargetExpr &&
                               index2Target is IArrayIndexerExpression index2TargetExpr)
                        {
                            if (indexTargetExpr.Indices.Count == 1 &&
                                indexTargetExpr.Indices[0] is IVariableReferenceExpression innerIndexTarget &&
                                index2TargetExpr.Indices.Count == 1 &&
                                index2TargetExpr.Indices[0] is IVariableReferenceExpression innerIndex2Target)
                            {
                                IForStatement indexTargetLoop = Recognizer.GetLoopForVariable(context, innerIndexTarget);
                                if (indexTargetLoop != null &&
                                    AreLoopsDisjoint(indexTargetLoop, target.Target, indexTargetExpr.Target) &&
                                    innerIndexTarget.Equals(innerIndex2Target))
                                {
                                    innerLoops.Add(indexTargetLoop);
                                    indexTarget  = indexTargetExpr.Target;
                                    index2Target = index2TargetExpr.Target;
                                }
                                else
                                {
                                    break;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                        WarnIfLocal(indexTarget, target.Target, iaie);
                        WarnIfLocal(index2Target, target.Target, iaie);
                        innerLoops.Reverse();
                        var loopSizes    = innerLoops.ListSelect(ifs => new[] { Recognizer.LoopSizeExpression(ifs) });
                        var newIndexVars = innerLoops.ListSelect(ifs => new[] { Recognizer.LoopVariable(ifs) });
                        // Build name of replacement variable from index values
                        StringBuilder sb = new StringBuilder("_item");
                        AppendIndexString(sb, target);
                        AppendIndexString(sb, iaie);
                        string name = ToString(target.Target) + sb.ToString();
                        VariableInformation varInfo = VariableInformation.GetVariableInformation(context, baseVar);
                        var indices = Recognizer.GetIndices(iaie);
                        newvd = varInfo.DeriveArrayVariable(stmts, context, name, loopSizes, newIndexVars, indices);
                        if (!context.InputAttributes.Has <DerivedVariable>(newvd))
                        {
                            context.InputAttributes.Set(newvd, new DerivedVariable());
                        }
                        IExpression getItems;
                        if (innerLoops.Count == 1)
                        {
                            getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <IReadOnlyList <PlaceHolder> >, IReadOnlyList <int>, IReadOnlyList <int>, PlaceHolder[]>(Collection.GetItemsFromJagged),
                                                                   new Type[] { tp }, target.Target, indexTarget, index2Target);
                        }
                        else if (innerLoops.Count == 2)
                        {
                            getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <IReadOnlyList <PlaceHolder> >, IReadOnlyList <IReadOnlyList <int> >, IReadOnlyList <IReadOnlyList <int> >, PlaceHolder[][]>(Collection.GetJaggedItemsFromJagged),
                                                                   new Type[] { tp }, target.Target, indexTarget, index2Target);
                        }
                        else
                        {
                            throw new NotImplementedException($"innerLoops.Count = {innerLoops.Count}");
                        }
                        context.InputAttributes.CopyObjectAttributesTo <Algorithm>(baseVar, context.OutputAttributes, getItems);
                        stmts.Add(Builder.AssignStmt(Builder.VarRefExpr(newvd), getItems));
                        var newIndices = newIndexVars.ListSelect(ivds => Util.ArrayInit(ivds.Length, i => Builder.VarRefExpr(ivds[i])));
                        newExpr = Builder.JaggedArrayIndex(Builder.VarRefExpr(newvd), newIndices);
                        rhsExpr = getItems;
                    }
                    else if (HasAnyCommonLoops(index, index2))
                    {
                        Warning($"This model will consume excess memory due to the indexing expression {iaie} since {index} and {index2} have larger depth than the compiler can handle.");
                    }
                }
Exemplo n.º 21
0
        private void CheckIssuesForReferencedLocalOrField(CheckCodeIssuesEventArgs ea, IForStatement loop, IElement lambda, IElement element)
        {
            if (element.ElementType == LanguageElementType.ElementReferenceExpression)
            {
                IElement declaration = element.GetDeclaration();
                if (declaration.ElementType == LanguageElementType.Variable || declaration.ElementType == LanguageElementType.InitializedVariable)
                {
                    if (loop.Initializers.Contains(declaration) || !declaration.IsParentedBy(loop))
                    {
                        ea.AddWarning(element.ToLanguageElement().Range, "Possible unintended closure scope misuse");
                    }
                }
                return;
            }

            foreach (IElement child in element.Children)
            {
                CheckIssuesForReferencedLocalOrField(ea, loop, lambda, child);
            }
        }
Exemplo n.º 22
0
 public override void TraverseChildren(IForStatement forStatement)
 {
     Result++;
     base.TraverseChildren(forStatement);
 }
Exemplo n.º 23
0
 public void Visit(IForStatement forStatement)
 {
     Contract.Requires(forStatement != null);
       throw new NotImplementedException();
 }
Exemplo n.º 24
0
        void WriteTable(TableInfo table, ICollection <IStatement> output)
        {
            string            writerName = VariableInformation.GenerateName(context, "_writer");
            ITypeDeclaration  td         = context.FindOutputForAncestor <ITypeDeclaration, ITypeDeclaration>();
            IFieldDeclaration fd         = Builder.FieldDecl(writerName, typeof(StreamWriter), td);

            fd.Documentation = "Writes " + table.Name;
            context.AddMember(fd);
            td.Fields.Add(fd);
            var                      writer = Builder.FieldRefExpr(fd);
            IForStatement            innerForStatement;
            IForStatement            fs = Builder.NestedForStmt(table.indexVars, table.sizes, out innerForStatement);
            ICollection <IStatement> output2;

            if (fs != null)
            {
                output.Add(fs);
                output2 = innerForStatement.Body.Statements;
            }
            else
            {
                output2 = output;
            }
            StringBuilder header = new StringBuilder();

            header.Append("iteration");
            output2.Add(GetWriteStatement(writer, Builder.VarRefExpr(iterationVar)));
            string delimiter      = UseToString ? "\t" : ",";
            var    writeDelimiter = GetWriteStatement(writer, Builder.LiteralExpr(delimiter));

            foreach (var indexVar in table.indexVars)
            {
                header.Append(delimiter);
                header.Append(indexVar.Name);
                output2.Add(writeDelimiter);
                output2.Add(GetWriteStatement(writer, Builder.VarRefExpr(indexVar)));
            }
            foreach (var messageBaseExpr in table.messageExprs)
            {
                Stack <IExpression> conditions = new Stack <IExpression>();
                object messageVar               = Recognizer.GetDeclaration(messageBaseExpr);
                VariableInformation varInfo     = VariableInformation.GetVariableInformation(context, messageVar);
                IExpression         messageExpr = messageBaseExpr;
                foreach (var bracket in varInfo.indexVars)
                {
                    if (!messageExpr.GetExpressionType().IsValueType)
                    {
                        conditions.Push(Builder.BinaryExpr(BinaryOperator.IdentityEquality, messageExpr, Builder.LiteralExpr(null)));
                    }
                    var indices = Util.ArrayInit(bracket.Length, i => Builder.VarRefExpr(bracket[i]));
                    messageExpr = Builder.ArrayIndex(messageExpr, indices);
                }
                if (!messageExpr.GetExpressionType().IsValueType)
                {
                    conditions.Push(Builder.BinaryExpr(BinaryOperator.IdentityEquality, messageExpr, Builder.LiteralExpr(null)));
                }
                if (messageExpr.GetExpressionType().IsPrimitive)
                {
                    header.Append(delimiter);
                    header.Append(varInfo.Name);
                    output2.Add(writeDelimiter);
                    output2.Add(GetWriteStatement(writer, AddConditions(messageExpr, conditions)));
                }
                else
                {
                    Dictionary <string, IExpression> dict = GetProperties(messageExpr);
                    foreach (var entry in dict)
                    {
                        header.Append(delimiter);
                        header.Append(varInfo.Name + entry.Key);
                        output2.Add(writeDelimiter);
                        output2.Add(GetWriteStatement(writer, AddConditions(entry.Value, conditions)));
                    }
                }
            }
            output2.Add(GetWriteLineStatement(writer));
            output.Add(GetFlushStatement(writer));
            if (traceWriterMethod == null)
            {
                MakeTraceWriterMethod();
            }
            fd.Initializer = Builder.StaticMethod(traceWriterMethod, Builder.LiteralExpr(table.Name), Builder.LiteralExpr(header.ToString()));
            if (disposeMethod == null)
            {
                MakeDisposeMethod();
            }
            disposeMethod.Body.Statements.Add(GetDisposeStatement(writer));
        }
Exemplo n.º 25
0
        protected override IStatement ConvertCondition(IConditionStatement ics)
        {
            context.SetPrimaryOutput(ics);
            ConvertExpression(ics.Condition);
            IForStatement    loop      = null;
            ConditionBinding binding   = GateTransform.GetConditionBinding(ics.Condition, context, out loop);
            IExpression      caseValue = binding.rhs;

            if (!GateTransform.IsLiteralOrLoopVar(context, caseValue, out loop))
            {
                Error("If statement condition must compare to a literal or loop counter, was: " + ics.Condition);
                return(ics);
            }
            bool        isStochastic = CodeRecognizer.IsStochastic(context, binding.lhs);
            IExpression gateBlockKey;

            if (isStochastic)
            {
                gateBlockKey = binding.lhs;
            }
            else
            {
                // definitions must not be unified across deterministic gate conditions
                gateBlockKey = binding.GetExpression();
            }
            GateBlock gateBlock             = null;
            Set <ConditionBinding> bindings = ConditionBinding.Copy(conditionContext);
            Dictionary <IExpression, GateBlock> blockMap;

            if (!gateBlocks.TryGetValue(bindings, out blockMap))
            {
                // first time seeing these bindings
                blockMap             = new Dictionary <IExpression, GateBlock>();
                gateBlocks[bindings] = blockMap;
            }
            if (!blockMap.TryGetValue(gateBlockKey, out gateBlock))
            {
                // first time seeing this lhs
                gateBlock = new GateBlock();
                blockMap[gateBlockKey] = gateBlock;
            }
            if (gateBlock.hasLoopCaseValue && loop == null)
            {
                Error("Cannot compare " + binding.lhs + " to a literal, since it was previously compared to a loop counter.  Put this test inside the loop.");
            }
            if (!gateBlock.hasLoopCaseValue && gateBlock.caseValues.Count > 0 && loop != null)
            {
                Error("Cannot compare " + binding.lhs + " to a loop counter, since it was previously compared to a literal.  Put the literal case inside the loop.");
            }
            gateBlock.caseValues.Add(caseValue);
            if (loop != null)
            {
                gateBlock.hasLoopCaseValue = true;
            }
            gateBlockContext.Add(gateBlock);
            context.OutputAttributes.Set(ics, gateBlock);
            int startIndex = conditionContext.Count;

            conditionContext.Add(binding);
            ConvertBlock(ics.Then);
            if (ics.Else != null)
            {
                conditionContext.RemoveRange(startIndex, conditionContext.Count - startIndex);
                binding = binding.FlipCondition();
                conditionContext.Add(binding);
                ConvertBlock(ics.Else);
            }
            conditionContext.RemoveRange(startIndex, conditionContext.Count - startIndex);
            gateBlockContext.RemoveAt(gateBlockContext.Count - 1);
            // remove any uses that match a def
            //RemoveUsesOfDefs(gateBlock);
            if (gateBlockContext.Count > 0)
            {
                GateBlock currentBlock = gateBlockContext[gateBlockContext.Count - 1];
                // all variables defined/used in the inner block must be processed by the outer block
                foreach (ExpressionWithBindings eb in gateBlock.variablesDefined.Values)
                {
                    if (eb.Bindings.Count > 0)
                    {
                        foreach (List <ConditionBinding> binding2 in eb.Bindings)
                        {
                            ProcessUse(eb.Expression, true, Union(conditionContext, binding2));
                        }
                    }
                    else
                    {
                        ProcessUse(eb.Expression, true, conditionContext);
                    }
                }
                foreach (List <ExpressionWithBindings> ebs in gateBlock.variablesUsed.Values)
                {
                    foreach (ExpressionWithBindings eb in ebs)
                    {
                        if (eb.Bindings.Count > 0)
                        {
                            foreach (ICollection <ConditionBinding> binding2 in eb.Bindings)
                            {
                                ProcessUse(eb.Expression, false, Union(conditionContext, binding2));
                            }
                        }
                        else
                        {
                            ProcessUse(eb.Expression, false, conditionContext);
                        }
                    }
                }
            }
            return(ics);
        }
 /// <summary>
 /// Rewrites the given for statement.
 /// </summary>
 /// <param name="forStatement"></param>
 public virtual IStatement Rewrite(IForStatement forStatement)
 {
     return forStatement;
 }
 protected override IStatement DoConvertStatement(IStatement ist)
 {
     if (ist is IExpressionStatement)
     {
         bool isAccumulator       = false;
         IExpressionStatement ies = (IExpressionStatement)ist;
         if (ies.Expression is IAssignExpression)
         {
             IAssignExpression iae = (IAssignExpression)ies.Expression;
             AccumulationInfo  ac  = context.InputAttributes.Get <AccumulationInfo>(ies);
             if (ac != null)
             {
                 // This statement defines an accumulator.
                 // Delete the statement and replace with any remaining accumulations.
                 if (!ac.isInitialized)
                 {
                     context.AddStatementBeforeCurrent(ac.initializer);
                 }
                 ac.isInitialized = false;
                 context.AddStatementsBeforeCurrent(ac.statements);
                 isAccumulator = true;
             }
             object ivd = Recognizer.GetVariableDeclaration(iae.Target);
             if (ivd == null)
             {
                 ivd = Recognizer.GetFieldReference(iae.Target);
             }
             if (ivd != null)
             {
                 MessageArrayInformation mai = context.InputAttributes.Get <MessageArrayInformation>(ivd);
                 bool oneUse = (mai != null) && (mai.useCount == 1);
                 List <AccumulationInfo> ais = context.InputAttributes.GetAll <AccumulationInfo>(ivd);
                 foreach (AccumulationInfo ai in ais)
                 {
                     if (!context.InputAttributes.Has <OperatorStatement>(ist))
                     {
                         if (oneUse)
                         {
                             return(null);        // remove the statement
                         }
                         else
                         {
                             continue;
                         }
                     }
                     // assuming that we only accumulate one statement, we should always initialize
                     if (true || !ai.isInitialized)
                     {
                         // add the initializer in the same containers as the original accumulation statement
                         int        ancIndex = ai.containers.GetMatchingAncestorIndex(context);
                         Containers missing  = ai.containers.GetContainersNotInContext(context, ancIndex);
                         context.AddStatementBeforeAncestorIndex(ancIndex, Containers.WrapWithContainers(ai.initializer, missing.outputs));
                         ai.isInitialized = true;
                     }
                     // This statement defines a variable that contributes to an accumulator.
                     IList <IStatement> stmts    = Builder.StmtCollection();
                     IExpression        target   = iae.Target;
                     Type        exprType        = target.GetExpressionType();
                     IExpression accumulator     = ai.accumulator;
                     Type        accumulatorType = ai.type;
                     int         rank;
                     Type        eltType = Util.GetElementType(exprType, out rank);
                     if (rank == 1 && eltType == accumulatorType)
                     {
                         // This statement defines an array of items to be accumulated.
                         VariableInformation varInfo = context.InputAttributes.Get <VariableInformation>(mai.ci.decl);
                         int indexingDepth           = Recognizer.GetIndexingDepth(iae.Target);
                         if (mai.loopVarInfo != null)
                         {
                             indexingDepth -= mai.loopVarInfo.indexVarRefs.Length;
                         }
                         IExpression          size     = varInfo.sizes[indexingDepth][0];
                         IVariableDeclaration indexVar = varInfo.indexVars[indexingDepth][0];
                         IForStatement        ifs      = Builder.ForStmt(indexVar, size);
                         target = Builder.ArrayIndex(target, Builder.VarRefExpr(indexVar));
                         ifs.Body.Statements.Add(ai.GetAccumulateStatement(context, accumulator, target));
                         stmts.Add(ifs);
                     }
                     else
                     {
                         Stack <IList <IExpression> > indexStack = new Stack <IList <IExpression> >();
                         while (exprType != accumulatorType && target is IArrayIndexerExpression)
                         {
                             // The accumulator is an array type, and this statement defines an element of the accumulator type.
                             // Peel off the indices of the target.
                             IArrayIndexerExpression iaie = (IArrayIndexerExpression)target;
                             indexStack.Push(iaie.Indices);
                             target          = iaie.Target;
                             accumulatorType = Util.GetElementType(accumulatorType);
                         }
                         while (indexStack.Count > 0)
                         {
                             // Attach the indices of the target to the accumulator, in reverse order that they were peeled.
                             accumulator = Builder.ArrayIndex(accumulator, indexStack.Pop());
                         }
                         if (exprType == accumulatorType)
                         {
                             if (oneUse && !isAccumulator)
                             {
                                 // convert
                                 //   msg = expr;
                                 // into
                                 //   T temp = expr;
                                 //   acc = SetToProduct(acc, temp);
                                 // and move into ai.statement.
                                 tempVarCount++;
                                 string name = "_temp" + tempVarCount;
                                 IVariableDeclaration tempVar      = Builder.VarDecl(name, exprType);
                                 IStatement           newStatement = Builder.AssignStmt(Builder.VarDeclExpr(tempVar), iae.Expression);
                                 context.AddStatementBeforeCurrent(newStatement);
                                 context.AddStatementBeforeCurrent(ai.GetAccumulateStatement(context, accumulator, Builder.VarRefExpr(tempVar)));
                                 return(null);
                             }
                             else
                             {
                                 // must keep the original statement.
                                 // add
                                 //   acc = SetToProduct(acc, msg);
                                 // to ai.statements.
                                 context.AddStatementAfterCurrent(ai.GetAccumulateStatement(context, accumulator, iae.Target));
                             }
                         }
                         else
                         {
                             Error("Unrecognized variable type: " + StringUtil.TypeToString(exprType));
                         }
                     }
                     Containers containers = new Containers(context);
                     containers = containers.Remove(ai.containers);
                     IList <IStatement> output2 = Builder.StmtCollection();
                     Containers.AddStatementWithContainers(output2, stmts, containers.inputs);
                     foreach (IStatement ist2 in output2)
                     {
                         context.AddStatementAfterCurrent(ist2);
                     }
                 }
             }
         }
         if (!isAccumulator)
         {
             return(ist);
         }
         else
         {
             return(null);
         }
     }
     else
     {
         return(base.DoConvertStatement(ist));
     }
 }
 public override void TraverseChildren(IForStatement forStatement)
 {
     throw new TranslationException("For statements are not handled");
 }
Exemplo n.º 29
0
 protected override IStatement ConvertFor(IForStatement ifs)
 {
     loopVariables.Add(Recognizer.LoopVariable(ifs));
     return(base.ConvertFor(ifs));
 }
Exemplo n.º 30
0
        /// <summary>
        /// Add localInfo for expr to the current containerInfo.
        /// </summary>
        /// <param name="decl"></param>
        /// <param name="expr"></param>
        /// <param name="localInfo"></param>
        /// <param name="closedContainer"></param>
        protected LocalInfo AddLocalInfo(object decl, IExpression expr, LocalInfo localInfo, IForStatement closedContainer)
        {
            if (containerInfos.Count == 0)
            {
                return(localInfo);
            }
            ContainerInfo containerInfo = containerInfos.Peek();
            UsageInfo     usageInfo;

            if (!containerInfo.usageInfoOfVariable.TryGetValue(decl, out usageInfo))
            {
                usageInfo = new UsageInfo();
                containerInfo.usageInfoOfVariable[decl] = usageInfo;
            }
            LocalInfo info;

            if (!usageInfo.localInfos.TryGetValue(expr, out info))
            {
                info = localInfo.Clone();
                info.containingStatements.IntersectWith(openContainers);
                IVariableDeclaration loopVar        = Recognizer.LoopVariable(closedContainer);
                int        index                    = info.containers.inputs.FindIndex(container => Containers.ContainersAreEqual(container, closedContainer, allowBrokenLoops: true, ignoreLoopDirection: true));
                bool       conditionsContainLoopVar = info.containers.inputs.Skip(index + 1).Any(container => Recognizer.GetVariables(GetContainerExpression(container)).Contains(loopVar));
                IStatement replacement              = null;
                if (conditionsContainLoopVar)
                {
                    replacement = Builder.BrokenForStatement(closedContainer);
                    info.containingStatements.Add(replacement);
                }
                else
                {
                    var  loopSize        = Recognizer.LoopSizeExpression(closedContainer);
                    bool loopMustExecute = false;
                    if (loopSize is ILiteralExpression ile)
                    {
                        int loopSizeAsInt = (int)ile.Value;
                        if (loopSizeAsInt > 0)
                        {
                            loopMustExecute = true;
                        }
                    }
                    if (!loopMustExecute)
                    {
                        var condition = Builder.BinaryExpr(loopSize, BinaryOperator.GreaterThan, Builder.LiteralExpr(0));
                        replacement = Builder.CondStmt(condition, Builder.BlockStmt());
                    }
                }
                if (info.containers.inputs.Contains(replacement))
                {
                    replacement = null;
                }
                if (replacement == null)
                {
                    info.containers = info.containers.Where(container => !Containers.ContainersAreEqual(container, closedContainer, true, true));
                }
                else
                {
                    // this only replaces containers.inputs
                    info.containers = info.containers.Replace(container => !Containers.ContainersAreEqual(container, closedContainer, true, true)
                        ? container
                        : replacement);
                }
                int previousCount = info.containers.Count;
                info.containers = Containers.RemoveInvalidConditions(info.containers, context);
                if (info.containers.Count != previousCount && expr is IArrayIndexerExpression)
                {
                    // when dropping conditionals, we need to show that if the indices were valid inside the conditionals, they remain valid outside the conditionals.
                    // This is automatically true if the indices match the indexVars.
                    expr = GetPrefixIndexedByIndexVars(expr);
                }
                usageInfo.localInfos[expr] = info;
            }
            else
            {
                info.Add(localInfo);
            }
            info.appearsInNestedLoop = true;
            return(info);
        }
Exemplo n.º 31
0
 public void Visit(IForStatement forStatement)
 {
     this.result = this.copier.Copy(forStatement);
 }
Exemplo n.º 32
0
        public override void TraverseChildren(IForStatement forStatement)
{ MethodEnter(forStatement);
            base.TraverseChildren(forStatement);
     MethodExit();   }
Exemplo n.º 33
0
 public virtual void onASTElement(IForStatement forStatement)
 {
 }
Exemplo n.º 34
0
 //^ ensures this.path.Count == old(this.path.Count);
 /// <summary>
 /// Traverses the given for statement.
 /// </summary>
 /// <param name="forStatement"></param>
 public virtual void Visit(IForStatement forStatement)
 {
     if (this.stopTraversal) return;
       //^ int oldCount = this.path.Count;
       this.path.Push(forStatement);
       this.Visit(forStatement.InitStatements);
       this.Visit(forStatement.Condition);
       this.Visit(forStatement.IncrementStatements);
       this.Visit(forStatement.Body);
       //^ assume this.path.Count == oldCount+1; //True because all of the virtual methods of this class promise not decrease this.path.Count.
       this.path.Pop();
 }
        /// <summary>
        /// Converts variable declarations inside loops into array declarations at the top level.
        /// </summary>
        /// <param name="ivde"></param>
        /// <returns></returns>
        protected override IExpression ConvertVariableDeclExpr(IVariableDeclarationExpression ivde)
        {
            IVariableDeclaration ivd   = ivde.Variable;
            bool isLoneDeclaration     = (context.FindAncestorIndex <IExpressionStatement>() == context.Depth - 2);
            List <IForStatement> loops = context.FindAncestors <IForStatement>();

            if (loops.Count == 0)
            {
                List <IConditionStatement> ifs = context.FindAncestors <IConditionStatement>();
                if (ifs.Count == 0)
                {
                    return(ivde);
                }
                // Add declaration outside the if
                IStatement outermostContainer = ifs[0];
                int        ancIndex           = context.GetAncestorIndex(outermostContainer);
                var        defaultExpr        = Builder.DefaultExpr(ivd.VariableType);
                var        assignSt           = Builder.AssignStmt(ivde, defaultExpr);
                context.OutputAttributes.Set(assignSt, new Initializer());
                context.AddStatementBeforeAncestorIndex(ancIndex, assignSt);
                if (isLoneDeclaration)
                {
                    return(null);
                }
                else
                {
                    return(Builder.VarRefExpr(ivd));
                }
            }
            // ignore declaration of a loop variable
            if (Recognizer.LoopVariable(loops[loops.Count - 1]) == ivd)
            {
                return(ivde);
            }

            // Declaration is inside one or more loops, find their sizes and index variables
            Type        type      = Builder.ToType(ivd.VariableType);
            Type        arrayType = type;
            LoopVarInfo lvi       = new LoopVarInfo(loops);

            for (int i = 0; i < loops.Count; i++)
            {
                IForStatement loop = loops[i];
                lvi.indexVarRefs[i] = Builder.VarRefExpr(Recognizer.LoopVariable(loop));
                arrayType           = Util.MakeArrayType(arrayType, 1);
            }
            Predicate <int> isPartitionedAtDepth = (depth => context.InputAttributes.Has <Partitioned>(Recognizer.GetVariableDeclaration(lvi.indexVarRefs[depth])));
            Type            messageType          = Distributions.Distribution.IsDistributionType(type)
                                   ? MessageTransform.GetDistributionType(arrayType, type, type, 0, loops.Count, isPartitionedAtDepth)
                                   : MessageTransform.GetArrayType(arrayType, type, 0, isPartitionedAtDepth);

            lvi.arrayvd       = Builder.VarDecl(ivd.Name, messageType);
            loopVarInfos[ivd] = lvi;
            MessageArrayInformation mai = context.InputAttributes.Get <MessageArrayInformation>(ivd);

            if (mai != null)
            {
                mai.loopVarInfo = lvi;
            }
            context.InputAttributes.CopyObjectAttributesTo(ivd, context.OutputAttributes, lvi.arrayvd);
            context.InputAttributes.Remove <VariableInformation>(lvi.arrayvd);

            VariableInformation vi  = VariableInformation.GetVariableInformation(context, ivd);
            VariableInformation vi2 = VariableInformation.GetVariableInformation(context, lvi.arrayvd);

            vi2.IsStochastic = vi.IsStochastic;

            // Initialise the array to the appropriate sizes
            // TODO: change to work over loop brackets not loops
            IExpression expr = Builder.VarDeclExpr(lvi.arrayvd);

            for (int i = 0; i < loops.Count; i++)
            {
                IForStatement        loop     = loops[i];
                IExpression          loopSize = Recognizer.LoopSizeExpression(loop);
                IExpressionStatement assignSt = Builder.AssignStmt(expr,
                                                                   MessageTransform.GetArrayCreateExpression(expr, expr.GetExpressionType(),
                                                                                                             new IExpression[] { loopSize }));
                context.OutputAttributes.Set(assignSt.Expression, new DescriptionAttribute("Create array for replicates of '" + ivd.Name + "'"));
                context.OutputAttributes.Set(assignSt, new Initializer());

                if (expr is IVariableDeclarationExpression)
                {
                    expr = Builder.VarRefExpr(lvi.arrayvd);
                }
                expr = Builder.ArrayIndex(expr, lvi.indexVarRefs[i]);
                vi2.indexVars.Add(new IVariableDeclaration[] { Recognizer.GetVariableDeclaration(lvi.indexVarRefs[i]) });
                vi2.sizes.Add(new IExpression[] { loopSize });

                // Add declaration outside the loop
                int ancIndex = context.GetAncestorIndex(loop);
                context.AddStatementBeforeAncestorIndex(ancIndex, assignSt);
            }
            vi2.indexVars.AddRange(vi.indexVars);
            vi2.sizes.AddRange(vi.sizes);
            // If the variable declaration was a statement by itself, then return null (i.e. delete the statement).
            if (isLoneDeclaration)
            {
                return(null);
            }
            // Return a reference to the newly created array
            else
            {
                return(expr);
            }
        }
 public override void Visit(IForStatement forStatement)
 {
     if(Process(forStatement)){visitor.Visit(forStatement);}
     base.Visit(forStatement);
 }
 public override void TraverseChildren(IForStatement forStatement) {
   throw new TranslationException("For statements are not handled");
 }
 public override void VisitForStatement(IForStatement forStatement, IHighlightingConsumer consumer)
 {
     VisitLoop(forStatement, consumer);
 }
Exemplo n.º 39
0
 /// <summary>
 /// Performs some computation with the given for statement.
 /// </summary>
 /// <param name="forStatement"></param>
 public virtual void Visit(IForStatement forStatement)
 {
 }
Exemplo n.º 40
0
 public override void TraverseChildren(IForStatement forStatement)
 {
     Result++;
     base.TraverseChildren(forStatement);
 }
Exemplo n.º 41
0
 /// <summary>
 /// Traverses the children of the for statement.
 /// </summary>
 public virtual void TraverseChildren(IForStatement forStatement)
 {
     Contract.Requires(forStatement != null);
       this.TraverseChildren((IStatement)forStatement);
       if (this.StopTraversal) return;
       this.Traverse(forStatement.InitStatements);
       if (this.StopTraversal) return;
       this.Traverse(forStatement.Condition);
       if (this.StopTraversal) return;
       this.Traverse(forStatement.IncrementStatements);
       if (this.StopTraversal) return;
       this.Traverse(forStatement.Body);
 }
Exemplo n.º 42
0
    /// <summary>
    /// Returns a deep copy of the given for statement.
    /// </summary>
    /// <param name="forStatement"></param>
    public ForStatement Copy(IForStatement forStatement) {
      Contract.Requires(forStatement != null);
      Contract.Ensures(Contract.Result<ForStatement>() != null);

      var mutableCopy = this.shallowCopier.Copy(forStatement);
      mutableCopy.InitStatements = this.Copy(mutableCopy.InitStatements);
      mutableCopy.Condition = this.Copy(mutableCopy.Condition);
      mutableCopy.IncrementStatements = this.Copy(mutableCopy.IncrementStatements);
      mutableCopy.Body = this.Copy(mutableCopy.Body);
      return mutableCopy;
    }
Exemplo n.º 43
0
 /// <summary>
 /// Performs some computation with the given for statement.
 /// </summary>
 /// <param name="forStatement"></param>
 public virtual void Visit(IForStatement forStatement)
 {
     this.Visit((IStatement)forStatement);
 }
Exemplo n.º 44
0
    /// <summary>
    /// Returns a shallow copy of the given for statement.
    /// </summary>
    /// <param name="forStatement"></param>
    public ForStatement Copy(IForStatement forStatement) {
      Contract.Requires(forStatement != null);
      Contract.Ensures(Contract.Result<ForStatement>() != null);

      var mutable = forStatement as ForStatement;
      if (mutable != null) return mutable.Clone();
      return new ForStatement(forStatement);
    }
Exemplo n.º 45
0
 public void Visit(IForStatement forStatement)
 {
     throw new NotImplementedException();
 }
Exemplo n.º 46
0
        protected override void DoConvertMethodBody(IList <IStatement> outputs, IList <IStatement> inputs)
        {
            List <int> whileNumberOfNode = new List <int>();
            List <int> fusedCountOfNode  = new List <int>();
            List <List <IStatement> > containersOfNode = new List <List <IStatement> >();
            // the code may have multiple while(true) loops, however these must be disjoint.
            // therefore we treat 'while' as one container, but give each loop a different 'while number'.
            int outerWhileCount         = 0;
            int currentOuterWhileNumber = 0;
            int currentFusedCount       = 0;
            List <Set <IVariableDeclaration> > loopVarsOfWhileNumber = new List <Set <IVariableDeclaration> >();
            // build the dependency graph
            var g = new DependencyGraph2(context, inputs, DependencyGraph2.BackEdgeHandling.Ignore,
                                         delegate(IWhileStatement iws)
            {
                if (iws is IFusedBlockStatement)
                {
                    if (iws.Condition is IVariableReferenceExpression)
                    {
                        currentFusedCount++;
                    }
                }
                else
                {
                    outerWhileCount++;
                    currentOuterWhileNumber = outerWhileCount;
                }
            },
                                         delegate(IWhileStatement iws)
            {
                if (iws is IFusedBlockStatement)
                {
                    if (iws.Condition is IVariableReferenceExpression)
                    {
                        currentFusedCount--;
                    }
                }
                else
                {
                    currentOuterWhileNumber = 0;
                }
            },
                                         delegate(IConditionStatement ics)
            {
            },
                                         delegate(IConditionStatement ics)
            {
            },
                                         delegate(IStatement ist, int targetIndex)
            {
                int whileNumber = currentOuterWhileNumber;
                whileNumberOfNode.Add(whileNumber);
                fusedCountOfNode.Add(currentFusedCount);
                List <IStatement> containers = new List <IStatement>();
                LoopMergingTransform.UnwrapStatement(ist, containers);
                containersOfNode.Add(containers);
                for (int i = 0; i < currentFusedCount; i++)
                {
                    if (containers[i] is IForStatement ifs)
                    {
                        var loopVar = Recognizer.LoopVariable(ifs);
                        if (loopVarsOfWhileNumber.Count <= whileNumber)
                        {
                            while (loopVarsOfWhileNumber.Count <= whileNumber)
                            {
                                loopVarsOfWhileNumber.Add(new Set <IVariableDeclaration>());
                            }
                        }
                        Set <IVariableDeclaration> loopVars = loopVarsOfWhileNumber[whileNumber];
                        loopVars.Add(loopVar);
                    }
                }
            });
            var nodes           = g.nodes;
            var dependencyGraph = g.dependencyGraph;

            for (int whileNumber = 1; whileNumber < loopVarsOfWhileNumber.Count; whileNumber++)
            {
                foreach (var loopVar in loopVarsOfWhileNumber[whileNumber])
                {
                    // Any statement (in the while loop) that has a forward descendant and a backward descendant will be cloned, so we want to minimize the number of such nodes.
                    // The free variables in this problem are the loop directions at the leaf statements, since all other loop directions are forced by these.
                    // We find the optimal labeling of the free variables by solving a min cut problem on a special network.
                    // The network is constructed so that the cost of a cut is equal to the number of statements that will be cloned.
                    // The network has 2 nodes for every statement: an in-node and an out-node.
                    // For a non-leaf statement, there is a capacity 1 edge from the in-node to out-node.  This edge is cut when the statement is cloned.
                    // For a leaf statement, there is an infinite capacity edge in both directions, or equivalently a single node.
                    // If statement A depends on statement B, then there is an infinite capacity edge from in-A to in-B, and from out-B to out-A,
                    // representing the fact that cloning A requires cloning B, but not the reverse.
                    // If a statement must appear with a forward loop, it is connected to the source.
                    // If a statement must appear with a backward loop, it is connected to the sink.

                    // construct a capacitated graph
                    int inNodeStart  = 0;
                    int outNodeStart = inNodeStart + dependencyGraph.Nodes.Count;
                    int sourceNode   = outNodeStart + dependencyGraph.Nodes.Count;
                    int sinkNode     = sourceNode + 1;
                    int cutNodeCount = sinkNode + 1;
                    Func <NodeIndex, int> getInNode       = node => node + inNodeStart;
                    Func <NodeIndex, int> getOutNode      = node => node + outNodeStart;
                    IndexedGraph          network         = new IndexedGraph(cutNodeCount);
                    const float           infinity        = 1000000f;
                    List <float>          capacity        = new List <float>();
                    List <NodeIndex>      nodesOfInterest = new List <NodeIndex>();
                    foreach (var node in dependencyGraph.Nodes)
                    {
                        if (whileNumberOfNode[node] != whileNumber)
                        {
                            continue;
                        }
                        NodeIndex         source             = node;
                        List <IStatement> containersOfSource = containersOfNode[source];
                        bool hasLoopVar = containersOfSource.Any(container => container is IForStatement && Recognizer.LoopVariable((IForStatement)container) == loopVar);
                        if (!hasLoopVar)
                        {
                            continue;
                        }
                        nodesOfInterest.Add(node);
                        IStatement sourceSt            = nodes[source];
                        var        readAfterWriteEdges = dependencyGraph.EdgesOutOf(source).Where(edge => !g.isWriteAfterRead[edge]);
                        bool       isLeaf  = true;
                        int        inNode  = getInNode(node);
                        int        outNode = getOutNode(node);
                        foreach (var target in readAfterWriteEdges.Select(dependencyGraph.TargetOf))
                        {
                            List <IStatement> containersOfTarget = containersOfNode[target];
                            IStatement        targetSt           = nodes[target];
                            ForEachMatchingLoopVariable(containersOfSource, containersOfTarget, (loopVar2, afs, bfs) =>
                            {
                                if (loopVar2 == loopVar)
                                {
                                    int inTarget  = getInNode(target);
                                    int outTarget = getOutNode(target);
                                    network.AddEdge(inTarget, inNode);
                                    capacity.Add(infinity);
                                    network.AddEdge(outNode, outTarget);
                                    capacity.Add(infinity);
                                    isLeaf = false;
                                }
                            });
                        }
                        if (isLeaf)
                        {
                            if (debug)
                            {
                                log.Add($"loopVar={loopVar.Name} leaf {sourceSt}");
                            }
                            network.AddEdge(inNode, outNode);
                            capacity.Add(infinity);
                            network.AddEdge(outNode, inNode);
                            capacity.Add(infinity);
                        }
                        else
                        {
                            network.AddEdge(inNode, outNode);
                            capacity.Add(1f);
                        }
                        int       fusedCount = fusedCountOfNode[node];
                        Direction desiredDirectionOfSource = GetDesiredDirection(loopVar, containersOfSource, fusedCount);
                        if (desiredDirectionOfSource == Direction.Forward)
                        {
                            if (debug)
                            {
                                log.Add($"loopVar={loopVar.Name} forward {sourceSt}");
                            }
                            network.AddEdge(sourceNode, inNode);
                            capacity.Add(infinity);
                        }
                        else if (desiredDirectionOfSource == Direction.Backward)
                        {
                            if (debug)
                            {
                                log.Add($"loopVar={loopVar.Name} backward {sourceSt}");
                            }
                            network.AddEdge(outNode, sinkNode);
                            capacity.Add(infinity);
                        }
                    }
                    network.IsReadOnly = true;

                    // compute the min cut
                    MinCut <NodeIndex, EdgeIndex> mc = new MinCut <EdgeIndex, EdgeIndex>(network, e => capacity[e]);
                    mc.Sources.Add(sourceNode);
                    mc.Sinks.Add(sinkNode);
                    Set <NodeIndex> sourceGroup = mc.GetSourceGroup();
                    foreach (NodeIndex node in nodesOfInterest)
                    {
                        IStatement sourceSt   = nodes[node];
                        bool       forwardIn  = sourceGroup.Contains(getInNode(node));
                        bool       forwardOut = sourceGroup.Contains(getOutNode(node));
                        if (forwardIn != forwardOut)
                        {
                            if (debug)
                            {
                                log.Add($"loopVar={loopVar.Name} will clone {sourceSt}");
                            }
                        }
                        else if (forwardIn)
                        {
                            if (debug)
                            {
                                log.Add($"loopVar={loopVar.Name} wants forward {sourceSt}");
                            }
                        }
                        else
                        {
                            if (debug)
                            {
                                log.Add($"loopVar={loopVar.Name} wants backward {sourceSt}");
                            }
                            var  containers    = containersOfNode[node];
                            bool isForwardLoop = true;
                            foreach (var container in containers)
                            {
                                if (container is IForStatement)
                                {
                                    IForStatement ifs = (IForStatement)container;
                                    if (Recognizer.LoopVariable(ifs) == loopVar)
                                    {
                                        isForwardLoop = Recognizer.IsForwardLoop(ifs);
                                    }
                                }
                            }
                            if (isForwardLoop)
                            {
                                Set <IVariableDeclaration> loopVarsToReverse;
                                if (!loopVarsToReverseInStatement.TryGetValue(sourceSt, out loopVarsToReverse))
                                {
                                    // TODO: re-use equivalent sets
                                    loopVarsToReverse = new Set <IVariableDeclaration>();
                                    loopVarsToReverseInStatement.Add(sourceSt, loopVarsToReverse);
                                }
                                loopVarsToReverse.Add(loopVar);
                            }
                        }
                    }
                }
            }

            base.DoConvertMethodBody(outputs, inputs);
        }
Exemplo n.º 47
0
 private void FixSpacingFor(IForStatement item)
 {
 }
            private void WriteForStatement(IForStatement statement, IFormatter formatter)
            {
                this.WriteStatementSeparator(formatter);

                formatter.WriteKeyword("for");
                formatter.Write(" (");
                this.forLoop = true;
                this.WriteStatement(statement.Initializer, formatter);
                formatter.Write("; ");
                this.WriteExpression(statement.Condition, formatter);
                formatter.Write("; ");
                this.WriteStatement(statement.Increment, formatter);
                formatter.Write(")");
                this.forLoop = false;
                formatter.Write(" {");
                formatter.WriteLine();
                formatter.WriteIndent();
                if (statement.Body != null)
                {
                    this.WriteStatement(statement.Body, formatter);
                }
                formatter.WriteLine();
                formatter.WriteOutdent();
                formatter.WriteKeyword("}");
            }
Exemplo n.º 49
0
        /// <summary>
        /// Collect all loops in the context whose index is referenced by expr or by the size expression of another collected loop.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="expr"></param>
        /// <param name="excludeAncestorIndex">Only loops whose ancestor index is greater than excludeAncestorIndex will be collected.</param>
        /// <param name="includeConditionals">Include condition statements</param>
        /// <returns>A list of IForStatements, starting with outermost.</returns>
        internal static List <IStatement> GetLoopsNeededForExpression(
            BasicTransformContext context, IExpression expr, int excludeAncestorIndex, bool includeConditionals)
        {
            List <IStatement> loopsNeeded = new List <IStatement>();
            List <IStatement> ancestors   = context.FindAncestorsBelow <IStatement>(excludeAncestorIndex);

            ancestors.Reverse();
            List <IExpression> containedExpressions = new List <IExpression>();

            AddToContainedExpressions(containedExpressions, expr, context);
            // loop ancestors starting from innermost
            foreach (IStatement ist in ancestors)
            {
                if (ist is IForStatement loop)
                {
                    IVariableDeclaration loopVar = Recognizer.LoopVariable(loop);
                    try
                    {
                        IExpression loopVarRef = Builder.VarRefExpr(loopVar);
                        foreach (IExpression containedExpression in containedExpressions)
                        {
                            if (Builder.ContainsExpression(containedExpression, loopVarRef))
                            {
                                IForStatement replacedLoop = Builder.ForStmt(Recognizer.LoopVariable(loop), Recognizer.LoopSizeExpression(loop));
                                loopsNeeded.Add(replacedLoop);
                                AddToContainedExpressions(containedExpressions, Recognizer.LoopSizeExpression(loop), context);
                                break;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        context.Error("GetLoopsNeededForExpression", ex);
                    }
                }
                else if (includeConditionals && (ist is IConditionStatement ics))
                {
                    bool found = false;
                    var  conditionVariables = Recognizer.GetVariables(ics.Condition).Select(Builder.VarRefExpr);
                    foreach (IExpression conditionVariable in conditionVariables)
                    {
                        foreach (IExpression containedExpression in containedExpressions)
                        {
                            if (Builder.ContainsExpression(containedExpression, conditionVariable))
                            {
                                loopsNeeded.Add(ics);
                                AddToContainedExpressions(containedExpressions, ics.Condition, context);
                                found = true;
                                break;
                            }
                        }
                        if (found)
                        {
                            break;
                        }
                    }
                }
            }
            loopsNeeded.Reverse();
            return(loopsNeeded);
        }
 /// <summary>
 /// Performs some computation with the given for statement.
 /// </summary>
 /// <param name="forStatement"></param>
 public virtual void Visit(IForStatement forStatement)
 {
 }
Exemplo n.º 51
0
        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);
        }
Exemplo n.º 52
0
 public override void TraverseChildren(IForStatement forStatement) {
   this.sourceEmitterOutput.Write("for (", true);
   this.TraverseInitializersOrIncrementers(forStatement.InitStatements);
   this.sourceEmitterOutput.Write("; ");
   this.Traverse(forStatement.Condition);
   this.sourceEmitterOutput.Write("; ");
   this.TraverseInitializersOrIncrementers(forStatement.IncrementStatements);
   this.sourceEmitterOutput.WriteLine(")");
   this.Traverse(forStatement.Body);
 }
Exemplo n.º 53
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="forStatement"></param>
 public ForStatement(IForStatement forStatement)
   : base(forStatement) {
   this.body = forStatement.Body;
   this.condition = forStatement.Condition;
   this.incrementStatements = new List<IStatement>(forStatement.IncrementStatements);
   this.initStatements = new List<IStatement>(forStatement.InitStatements);
 }
        private IForStatement ConvertForWithDistributedSchedule(IForStatement ifs, IVariableDeclaration loopVar, DistributedScheduleExpression dse)
        {
            if (dse.scheduleExpression == null && dse.schedulePerThreadExpression == null)
            {
                return((IForStatement)base.ConvertFor(ifs));
            }
            Sequential attr = context.InputAttributes.Get <Sequential>(loopVar);

            if (attr == null || !attr.BackwardPass)
            {
                Error($"Range '{loopVar.Name}' has a DistributedSchedule attribute but does not have a Sequential attribute with BackwardPass = true");
            }
            // Convert this loop into for(stage) for(indexInBlock) { ... }
            IVariableDeclaration loopVarBlock   = VariableInformation.GenerateLoopVar(context, loopVar.Name + "_Block");
            Sequential           sequentialAttr = new Sequential();

            context.OutputAttributes.Set(loopVarBlock, sequentialAttr);
            bool isBackwardLoop = !Recognizer.IsForwardLoop(ifs);

            this.distributedCommunicationExpressions.Clear();
            IForStatement loopInBlock;
            IExpression   zero = Builder.LiteralExpr(0);
            IExpression   distributedStageCount;

            if (dse.schedulePerThreadExpression != null)
            {
                var scheduleForBlock = Builder.ArrayIndex(dse.schedulePerThreadExpression, Builder.VarRefExpr(loopVarBlock));
                distributedStageCount = Builder.PropRefExpr(dse.schedulePerThreadExpression, typeof(int[][][][]), "Length");
                loopInBlock           = ConvertForWithParallelSchedule(ifs, loopVar, new ParallelScheduleExpression(scheduleForBlock));
            }
            else
            {
                IVariableDeclaration loopVarInBlock = VariableInformation.GenerateLoopVar(context, loopVar.Name + "_inBlock");
                context.OutputAttributes.Set(loopVarInBlock, sequentialAttr);
                if (!dse.scheduleExpression.GetExpressionType().Equals(typeof(int[][])))
                {
                    Error("argument to DistributedSchedule attribute is not of type int[][]");
                }
                IExpression itemsInBlock     = Builder.ArrayIndex(dse.scheduleExpression, Builder.VarRefExpr(loopVarBlock));
                IExpression itemCountInBlock = Builder.PropRefExpr(itemsInBlock, typeof(int[]), "Length");
                distributedStageCount = Builder.PropRefExpr(dse.scheduleExpression, typeof(int[][]), "Length");
                loopInBlock           = Builder.ForStmt(loopVarInBlock, itemCountInBlock);
                if (isBackwardLoop)
                {
                    Recognizer.ReverseLoopDirection(loopInBlock);
                }
                var assignLoopVar = Builder.AssignStmt(Builder.VarDeclExpr(loopVar), Builder.ArrayIndex(itemsInBlock, Builder.VarRefExpr(loopVarInBlock)));
                loopInBlock.Body.Statements.Add(assignLoopVar);
                ConvertStatements(loopInBlock.Body.Statements, ifs.Body.Statements);
            }
            IForStatement loopBlock = Builder.ForStmt(loopVarBlock, distributedStageCount);
            IExpression   commExpr  = dse.commExpression;

            if (isBackwardLoop)
            {
                loopBlock.Body.Statements.Add(loopInBlock);
                foreach (var tuple in this.distributedCommunicationExpressions)
                {
                    var         arrayExpr         = tuple.Item1;
                    var         dce               = tuple.Item2;
                    IExpression sendExpr          = Builder.ArrayIndex(dce.arrayIndicesToSendExpression, Builder.VarRefExpr(loopVarBlock));
                    IExpression receiveExpr       = Builder.ArrayIndex(dce.arrayIndicesToReceiveExpression, Builder.VarRefExpr(loopVarBlock));
                    var         sendReceiveMethod = Builder.StaticGenericMethod(new Action <ICommunicator, IList <PlaceHolder>, int[][], int[][]>(Communicator.AlltoallSubarrays),
                                                                                new Type[] { Utilities.Util.GetElementType(arrayExpr.GetExpressionType()) },
                                                                                commExpr, arrayExpr,
                                                                                receiveExpr,
                                                                                sendExpr);
                    loopBlock.Body.Statements.Add(Builder.ExprStatement(sendReceiveMethod));
                }
                Recognizer.ReverseLoopDirection(loopBlock);
            }
            else
            {
                foreach (var tuple in this.distributedCommunicationExpressions)
                {
                    var         arrayExpr         = tuple.Item1;
                    var         dce               = tuple.Item2;
                    IExpression sendExpr          = Builder.ArrayIndex(dce.arrayIndicesToSendExpression, Builder.VarRefExpr(loopVarBlock));
                    IExpression receiveExpr       = Builder.ArrayIndex(dce.arrayIndicesToReceiveExpression, Builder.VarRefExpr(loopVarBlock));
                    var         sendReceiveMethod = Builder.StaticGenericMethod(new Action <ICommunicator, IList <PlaceHolder>, int[][], int[][]>(Communicator.AlltoallSubarrays),
                                                                                new Type[] { Utilities.Util.GetElementType(arrayExpr.GetExpressionType()) },
                                                                                commExpr, arrayExpr,
                                                                                sendExpr,
                                                                                receiveExpr);
                    loopBlock.Body.Statements.Add(Builder.ExprStatement(sendReceiveMethod));
                }
                loopBlock.Body.Statements.Add(loopInBlock);
            }
            return(loopBlock);
        }
 private void FixSpacingFor(IForStatement item)
 {
 }
Exemplo n.º 56
0
 /// <summary>
 /// Visits the specified for statement.
 /// </summary>
 /// <param name="forStatement">For statement.</param>
 public override void Visit(IForStatement forStatement)
 {
     ForStatement mutableForStatement = new ForStatement(forStatement);
     this.resultStatement = this.myCodeCopier.DeepCopy(mutableForStatement);
 }
Exemplo n.º 57
0
        /// <summary>
        /// Only converts the contained statements in a for loop, leaving the initializer,
        /// condition and increment statements unchanged.
        /// </summary>
        /// <remarks>This method includes a number of checks to ensure the loop is valid e.g. that the initializer, condition and increment
        /// are all of the appropriate form.</remarks>
        protected override IStatement ConvertFor(IForStatement ifs)
        {
            IForStatement fs = Builder.ForStmt();

            context.SetPrimaryOutput(fs);
            // Check condition is valid
            fs.Condition = ifs.Condition;
            if ((!(fs.Condition is IBinaryExpression)) || (((IBinaryExpression)fs.Condition).Operator != BinaryOperator.LessThan))
            {
                Error("For statement condition must be of the form 'indexVar<loopSize', was " + fs.Condition);
            }

            // Check increment is valid
            fs.Increment = ifs.Increment;
            IExpressionStatement ies = fs.Increment as IExpressionStatement;
            bool validIncrement      = false;

            if (ies != null)
            {
                if (ies.Expression is IAssignExpression)
                {
                    IAssignExpression iae = (IAssignExpression)ies.Expression;
                    IBinaryExpression ibe = RemoveCast(iae.Expression) as IBinaryExpression;
                    validIncrement = (ibe != null) && (ibe.Operator == BinaryOperator.Add);
                }
                else if (ies.Expression is IUnaryExpression)
                {
                    IUnaryExpression iue = (IUnaryExpression)ies.Expression;
                    validIncrement = (iue.Operator == UnaryOperator.PostIncrement);
                }
            }
            if (!validIncrement)
            {
                Error("For statement increment must be of the form 'varname++' or 'varname=varname+1', was " + fs.Increment + ".");
            }


            // Check initializer is valid
            fs.Initializer = ifs.Initializer;
            ies            = fs.Initializer as IExpressionStatement;
            if (ies == null)
            {
                Error("For statement initializer must be an expression statement, was " + fs.Initializer.GetType());
            }
            else
            {
                if (!(ies.Expression is IAssignExpression))
                {
                    Error("For statement initializer must be an assignment, was " + fs.Initializer.GetType().Name);
                }
                else
                {
                    IAssignExpression iae2 = (IAssignExpression)ies.Expression;
                    if (!(iae2.Target is IVariableDeclarationExpression))
                    {
                        Error("For statement initializer must be a variable declaration, was " + iae2.Target.GetType().Name);
                    }
                    if (!Recognizer.IsLiteral(iae2.Expression, 0))
                    {
                        Error("Loop index must start at 0, was " + iae2.Expression);
                    }
                }
            }

            fs.Body = ConvertBlock(ifs.Body);
            return(fs);
        }
Exemplo n.º 58
0
 /// <summary>
 /// Returns a deep copy of the given for statement.
 /// </summary>
 /// <param name="forStatement"></param>
 public ForStatement Copy(IForStatement forStatement)
 {
     var mutableCopy = this.shallowCopier.Copy(forStatement);
       mutableCopy.InitStatements = this.Copy(mutableCopy.InitStatements);
       mutableCopy.Condition = this.Copy(mutableCopy.Condition);
       mutableCopy.IncrementStatements = this.Copy(mutableCopy.IncrementStatements);
       mutableCopy.Body = this.Copy(mutableCopy.Body);
       return mutableCopy;
 }
Exemplo n.º 59
0
 public override void TraverseChildren(IForStatement forStatement)
 {
     MethodEnter(forStatement);
     base.TraverseChildren(forStatement);
     MethodExit();
 }
Exemplo n.º 60
0
 /// <summary>
 /// Returns a shallow copy of the given for statement.
 /// </summary>
 /// <param name="forStatement"></param>
 public ForStatement Copy(IForStatement forStatement)
 {
     return new ForStatement(forStatement);
 }