Beispiel #1
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);
        }