private void SetLoopPriorities(DependencyGraph g) { var ssinfo = SchedulingTransform.GetSerialSchedulingInfo(g); var infos = ssinfo.loopInfos; var loopVarCount = analysis.loopVarCount; // sort infos by decreasing number of nodes infos.Sort((info1, info2) => Comparer <int> .Default.Compare(loopVarCount[info2.loopVar], loopVarCount[info1.loopVar])); // attach loop ordering information for LoopMergingTransform List <IVariableDeclaration> loopVars = new List <IVariableDeclaration>(loopVarCount.Keys); if (loopVars.Count > 0) { int maxCount = loopVarCount.Values.Max() + 1; // ensure Sequential loops have highest priority foreach (var info in infos) { loopVarCount[info.loopVar] += maxCount; } // sort loopVars by decreasing number of nodes loopVars.Sort((loopVar1, loopVar2) => Comparer <int> .Default.Compare(loopVarCount[loopVar2], loopVarCount[loopVar1])); for (int i = 0; i < loopVars.Count; i++) { IVariableDeclaration loopVar = loopVars[i]; context.OutputAttributes.Set(loopVar, new LoopPriority() { Priority = 1 + loopVars.Count - i }); } } }
/// <summary> /// Collect statements that need to re-execute due to initialization. /// </summary> /// <param name="blocks"></param> /// <param name="dependencyGraph"></param> /// <param name="stmts"></param> /// <param name="nodesToMove">Modified on exit</param> private Dictionary <Loop, IBlockStatement> GetFirstIterPostprocessing(List <StatementBlock> blocks, DirectedGraphFilter <NodeIndex, EdgeIndex> dependencyGraph, IList <IStatement> stmts, ICollection <NodeIndex> nodesToMove) { var hasUserInitializedAncestor = dependencyGraph.CreateNodeData(false); DepthFirstSearch <NodeIndex> dfsInitBlock = new DepthFirstSearch <int>(dependencyGraph.SourcesOf, dependencyGraph); List <NodeIndex> nodesToRerun = new List <NodeIndex>(); dfsInitBlock.FinishNode += delegate(NodeIndex node) { var stmt = stmts[node]; if (SchedulingTransform.IsUserInitialized(context, stmt)) { // do nothing } else if (SchedulingTransform.HasUserInitializedInitializer(context, stmt)) { hasUserInitializedAncestor[node] = true; nodesToMove.Add(node); nodesToRerun.Add(node); } else { var inherit = dependencyGraph.SourcesOf(node).Any(source => hasUserInitializedAncestor[source]); if (inherit) { hasUserInitializedAncestor[node] = true; nodesToRerun.Add(node); } } }; Dictionary <Loop, IBlockStatement> firstIterPostprocessing = new Dictionary <Loop, IBlockStatement>(); foreach (StatementBlock block in blocks) { if (block is Loop) { Loop loop = (Loop)block; // find the set of initialized nodes that are ancestors of the loop (and not ancestors of an ancestor loop) // find all nodes that are ancestors of the loop and descendants of (and including) the init nodes - cannot contain any loops // because we do not clear dfs, all previous stmts in loops are excluded. dfsInitBlock.SearchFrom(loop.indices); foreach (var i in loop.indices) { nodesToMove.Remove(i); nodesToRerun.Remove(i); } if (nodesToRerun.Count > 0) { var firstIterPost = Builder.BlockStmt(); foreach (var node in nodesToRerun) { IStatement stmt = stmts[node]; if (nodesToMove.Contains(node)) { firstIterPost.Statements.Add(stmt); } else { // clone the statement this.ShallowCopy = true; var convertedStmt = ConvertStatement(stmt); this.ShallowCopy = false; firstIterPost.Statements.Add(convertedStmt); loopMergingInfo.AddEquivalentStatement(convertedStmt, loopMergingInfo.GetIndexOf(stmt)); clonesOfStatement.Add(stmt, new List <IStatement>() { convertedStmt }); } } firstIterPostprocessing.Add(loop, firstIterPost); nodesToRerun.Clear(); } } } return(firstIterPostprocessing); }