Пример #1
0
        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
                    });
                }
            }
        }
Пример #2
0
        /// <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);
        }