/// <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); }