private void PostProcessDependencies(ICollection <IStatement> outputs)
 {
     if (replacements.Count > 0)
     {
         // contexts are bodies of innermost while statements
         DeadCodeTransform.ForEachStatement(outputs,
                                            delegate(IWhileStatement iws)
         {
         },
                                            delegate(IWhileStatement iws)
         {
         },
                                            _ =>
         {
         },
                                            _ =>
         {
         },
                                            delegate(IStatement ist)
         {
             if (replacements != null)
             {
                 DependencyInformation di = context.InputAttributes.Get <DependencyInformation>(ist);
                 if (di != null)
                 {
                     // must make a clone since this statement may appear in multiple contexts
                     DependencyInformation di2 = (DependencyInformation)di.Clone();
                     di2.Replace(replacements);
                     context.OutputAttributes.Remove <DependencyInformation>(ist);
                     context.OutputAttributes.Set(ist, di2);
                 }
             }
         });
     }
 }
Esempio n. 2
0
 public void AddDBMapping(string dbKey, string cacheKey, ExpirationHint hint)
 {
     lock (_dbKeysMappingTbl.SyncRoot)
     {
         _dbKeysMappingTbl[dbKey] = new DependencyInformation(cacheKey, hint);
     }
 }
Esempio n. 3
0
        private void ForEachInitializer(IStatement source, NodeIndex target, DependencyGraph2 g, Action <IStatement> action)
        {
            Stack <IStatement> todo = new Stack <IStatement>();

            todo.Push(source);
            while (todo.Count > 0)
            {
                IStatement            source2 = todo.Pop();
                DependencyInformation di2     = context.InputAttributes.Get <DependencyInformation>(source2);
                if (di2 == null)
                {
                    context.Error("Dependency information not found for statement: " + source2);
                    continue;
                }
                foreach (IStatement init in di2.Overwrites)
                {
                    int initIndex = g.indexOfNode[init];
                    if (initIndex < target)
                    {
                        // found a valid initializer
                        action(init);
                    }
                    else
                    {
                        // keep looking backward for a valid initializer
                        todo.Push(init);
                    }
                }
            }
        }
        protected override void DoConvertMethodBody(IList <IStatement> outputs, IList <IStatement> inputs)
        {
            Dictionary <IStatement, IStatement> replacements = new Dictionary <IStatement, IStatement>(ReferenceEqualityComparer <IStatement> .Instance);

            ProcessStatements(outputs, outputs, inputs, replacements);
            // update all dependencies
            foreach (IStatement ist in outputs)
            {
                if (ist is IWhileStatement)
                {
                    IWhileStatement iws = (IWhileStatement)ist;
                    foreach (IStatement st in iws.Body.Statements)
                    {
                        DependencyInformation di2 = context.OutputAttributes.Get <DependencyInformation>(st);
                        if (di2 != null)
                        {
                            di2.Replace(replacements);
                        }
                    }
                }
                else
                {
                    DependencyInformation di = context.OutputAttributes.Get <DependencyInformation>(ist);
                    if (di != null)
                    {
                        di.Replace(replacements);
                    }
                }
            }
        }
        public void IsPositiveFactorInfo()
        {
            FactorManager.FactorInfo info = FactorManager.GetFactorInfo(new Func <double, bool>(Factor.IsPositive));
            Assert.True(info.IsDeterministicFactor);
            var parameterTypes = new Dictionary <string, Type>
            {
                ["isPositive"] = typeof(bool),
                ["x"]          = typeof(Gaussian)
            };
            MessageFcnInfo fcninfo = info.GetMessageFcnInfo(factorManager, "AverageConditional", "x", parameterTypes);

            Assert.True(fcninfo.NotSupportedMessage == null);
            CheckMessageFcnInfo(fcninfo, info);

            DependencyInformation depInfo = FactorManager.GetDependencyInfo(fcninfo.Method);

            Assert.Throws <NotSupportedException>(() =>
            {
                fcninfo = info.GetMessageFcnInfo(factorManager, "AverageLogarithm", "x", parameterTypes);
            });
            bool found = false;

            foreach (MessageFcnInfo fcninfo2 in info.GetMessageFcnInfos("AverageLogarithm", null, null))
            {
                CheckMessageFcnInfo(fcninfo2, info);
                if (fcninfo2.TargetParameter.Equals("x"))
                {
                    Assert.True(fcninfo2.NotSupportedMessage != null);
                    found = true;
                }
            }
            Assert.True(found);
            fcninfo = info.GetMessageFcnInfo(factorManager, "LogAverageFactor", "", parameterTypes);
            CheckMessageFcnInfo(fcninfo, info);
        }
 protected override IStatement DoConvertStatement(IStatement ist)
 {
     DependencyInformation di = context.InputAttributes.Get<DependencyInformation>(ist);
     if (di != null && !indexOfStatement.ContainsKey(ist))
     {
         RemoveRedundantDependencies(ist, di);
         int index = indexOfStatement.Count;
         indexOfStatement.Add(ist, index);
     }
     IStatement st = base.DoConvertStatement(ist);
     return st;
 }
        protected override IStatement DoConvertStatement(IStatement ist)
        {
            if (ist is IWhileStatement)
            {
                return(ConvertWhile((IWhileStatement)ist));
            }
            if (replacements.ContainsKey(ist))
            {
                return(null);
            }
            bool isIncrement = context.InputAttributes.Has <IncrementStatement>(ist);

            if (this.inWhileLoop == false)
            {
                if (isIncrement)
                {
                    replacements[ist] = null;
                    return(null);
                }
            }
            else if (incrementStatements.Count > 0)
            {
                var attr = context.GetAttribute <HasIncrement>(ist);
                if (attr != null && incrementStatements.Contains(attr.incrementStatement))
                {
                    // hoist this statement out of the while loop.
                    // TODO: hoisting ist is only valid if its requirements are met when hoisted.
                    context.AddStatementBeforeAncestorIndex(ancestorIndexOfWhile, ist);
                    return(null);
                }
                else if (isIncrement)
                {
                    // Add to the initializerSet (assuming the non-increment statement is hoisted).
                    // This will only work correctly if the non-increment is in DependencyInformation.Initializers.
                    // This code currently does nothing since InitializerSet is only attached later by SchedulingTransform.
                    var iws            = context.GetAncestor(ancestorIndexOfWhile);
                    var initializerSet = context.GetAttribute <InitializerSet>(iws);
                    if (initializerSet != null)
                    {
                        initializerSet.initializers.Add(ist);
                    }
                }
            }
            DependencyInformation di = context.GetAttribute <DependencyInformation>(ist);

            if (di != null)
            {
                di.Replace(replacements);
            }
            visitedStatements.Add(ist);
            return(base.DoConvertStatement(ist));
        }
        internal void ToMessageTest()
        {
            FactorManager.FactorInfo info = FactorManager.GetFactorInfo(new Func <double, bool>(Factor.IsPositive));
            var parameterTypes            = new Dictionary <string, Type>
            {
                ["isPositive"] = typeof(bool),
                ["x"]          = typeof(Gaussian)
            };
            MessageFcnInfo fcninfo;

            fcninfo = info.GetMessageFcnInfo(factorManager, "LogEvidenceRatio2", "", parameterTypes);
            CheckMessageFcnInfo(fcninfo, info);
            DependencyInformation depInfo = FactorManager.GetDependencyInfo(fcninfo.Method);
        }
        private void RemoveRedundantDependencies(IStatement ist, DependencyInformation di)
        {
            // collapse dependencies that have the same unique index.
            Dictionary <int, KeyValuePair <int, IStatement> > nodeOfUniqueIndex = new Dictionary <int, KeyValuePair <int, IStatement> >();
            Set <IStatement> sourcesToRemove = new Set <IStatement>(ReferenceEqualityComparer <IStatement> .Instance);

            foreach (IStatement source in di.GetDependenciesOfType(DependencyType.Dependency))
            {
                int sourceIndex;
                if (indexOfStatement.TryGetValue(source, out sourceIndex))
                {
                    int uniqueIndex = loopMergingInfo.GetIndexOf(source);
                    KeyValuePair <int, IStatement> previousEntry;
                    if (nodeOfUniqueIndex.TryGetValue(uniqueIndex, out previousEntry))
                    {
                        int previousNode = previousEntry.Key;
                        // ist depends on two equivalent statements.
                        // only keep a dependency on the later statement.
                        if (sourceIndex > previousNode)
                        {
                            // source is the later statement.
                            nodeOfUniqueIndex[uniqueIndex] = new KeyValuePair <int, IStatement>(sourceIndex, source);
                            sourcesToRemove.Add(previousEntry.Value);
                        }
                        else
                        {
                            // source is the earlier statement.
                            sourcesToRemove.Add(source);
                        }
                    }
                    else
                    {
                        nodeOfUniqueIndex.Add(uniqueIndex, new KeyValuePair <int, IStatement>(sourceIndex, source));
                    }
                }
            }
            if (sourcesToRemove.Count > 0)
            {
                if (debugBlock != null)
                {
                    debugBlock.Statements.Add(Builder.CommentStmt($"dropping dependency of {ist} on {sourcesToRemove}"));
                }
                di.RemoveAll(sourcesToRemove.Contains);
            }
        }
Esempio n. 10
0
        public void IsPositiveFactorInfo()
        {
            FactorManager.FactorInfo info = FactorManager.GetFactorInfo(new Func <double, bool>(Factor.IsPositive));
            Console.WriteLine(info);
            Assert.True(info.IsDeterministicFactor);
            IDictionary <string, Type> parameterTypes = new Dictionary <string, Type>();

            parameterTypes["isPositive"] = typeof(bool);
            parameterTypes["x"]          = typeof(Gaussian);
            MessageFcnInfo fcninfo = info.GetMessageFcnInfo(factorManager, "AverageConditional", "x", parameterTypes);

            Assert.True(fcninfo.NotSupportedMessage == null);
            CheckMessageFcnInfo(fcninfo, info);

            DependencyInformation depInfo = FactorManager.GetDependencyInfo(fcninfo.Method);

            Console.WriteLine("Dependencies:");
            Console.WriteLine(StringUtil.ToString(depInfo.Dependencies));
            Console.WriteLine("Requirements:");
            Console.WriteLine(StringUtil.ToString(depInfo.Requirements));

            try
            {
                fcninfo = info.GetMessageFcnInfo(factorManager, "AverageLogarithm", "x", parameterTypes);
                Assert.True(false, "did not throw exception");
            }
            catch (NotSupportedException ex)
            {
                Console.WriteLine("Correctly failed with exception: " + ex);
            }
            bool found = false;

            foreach (MessageFcnInfo fcninfo2 in info.GetMessageFcnInfos("AverageLogarithm", null, null))
            {
                CheckMessageFcnInfo(fcninfo2, info);
                if (fcninfo2.TargetParameter.Equals("x"))
                {
                    Assert.True(fcninfo2.NotSupportedMessage != null);
                    found = true;
                }
            }
            Assert.True(found);
            fcninfo = info.GetMessageFcnInfo(factorManager, "LogAverageFactor", "", parameterTypes);
            CheckMessageFcnInfo(fcninfo, info);
        }
Esempio n. 11
0
        //CodeTransformer ct = new CodeTransformer();
        protected Node AddNode(GraphWriter g, IStatement ist, Stage stage)
        {
            if (ist is ICommentStatement)
            {
                return(null);
            }
            Node nd = GetNodeForStatement(ist, stage);

            if (nd != null)
            {
                nd.Label = Count + "," + nd.Label;
                Count++;
                return(nd);
            }
            DependencyInformation di = context.InputAttributes.Get <DependencyInformation>(ist);

            if ((di != null) && (di.IsOutput))
            {
                return(null);
            }
            string s = Count + ". " + StatementLabel(ist);

            nd          = g.AddNode("node" + Count);
            nd.UserData = Count++;
            SetNodeForStatement(ist, stage, nd);
            //if (di.IsOutput) nd.Fillcolor = Color.LightBlue;
            nd.Label = s;
            if (stage == Stage.Initialisation)
            {
                nd.FillColor = Color.LightGray;
            }
            if (ist is IExpressionStatement)
            {
                IExpressionStatement ies = (IExpressionStatement)ist;
                IAssignExpression    iae = ies.Expression as IAssignExpression;
                if ((iae != null) && (iae.Target is IVariableDeclarationExpression))
                {
                    nd.BorderWidth = 2;
                }
            }
            nd.Shape    = ShapeStyle.Box;
            nd.FontSize = 9;
            return(nd);
        }
Esempio n. 12
0
 /// <summary>
 /// Copy constructor.
 /// </summary>
 /// <param name="that"></param>
 public MessageFcnInfo(MessageFcnInfo that)
 {
     Method                 = that.Method;
     TargetParameter        = that.TargetParameter;
     Suffix                 = that.Suffix;
     IsStochastic           = that.IsStochastic;
     Dependencies           = that.Dependencies;
     Requirements           = that.Requirements;
     Triggers               = that.Triggers;
     SkipIfAllUniform       = that.SkipIfAllUniform;
     NotSupportedMessage    = that.NotSupportedMessage;
     factorEdgeOfParameter  = that.factorEdgeOfParameter;
     DependencyInfo         = that.DependencyInfo;
     IsMultiplyAll          = that.IsMultiplyAll;
     ReturnedParameterIndex = that.ReturnedParameterIndex;
     ReturnedInAllElementsParameterIndex = that.ReturnedInAllElementsParameterIndex;
     ResultParameterIndex      = that.ResultParameterIndex;
     ResultIndexParameterIndex = that.ResultIndexParameterIndex;
 }
Esempio n. 13
0
 protected void AddDependencyEdges(Graph g, Node nd, DependencyInformation di, Stage stage, Stage parentStage)
 {
     foreach (IStatement source in di.GetDependenciesOfType(DependencyType.Dependency | DependencyType.Declaration))
     {
         Node nd2 = GetNodeForStatement(source, stage);
         if (nd2 == null)
         {
             continue;
         }
         bool backwards = ((int)nd.UserData) < ((int)nd2.UserData);
         //Console.WriteLine("stage=" + stage + " " + nd.UserData + " " + nd2.UserData);
         Edge e;
         if (backwards)
         {
             e                        = g.AddEdge(nd.Attr.Id, nd2.Attr.Id);
             e.Attr.Color             = Color.Red;
             e.Attr.ArrowheadAtSource = ArrowStyle.Normal;
             e.Attr.ArrowheadAtTarget = ArrowStyle.None;
         }
         else
         {
             e = g.AddEdge(nd2.Attr.Id, nd.Attr.Id);
             if (parentStage != stage)
             {
                 e.Attr.Color = Color.LightGray;
             }
         }
         if (di.HasDependency(DependencyType.Trigger, source))
         {
             e.Attr.LineWidth = 2;
         }
         if (di.HasDependency(DependencyType.Fresh, source))
         {
             e.Attr.AddStyle(Style.Dashed);
         }
         if (di.HasDependency(DependencyType.Cancels, source))
         {
             e.Attr.Color = Color.LightGray;
         }
     }
     //e.LabelText = StatementLabel(ist);            e.Label.FontSize = 8;
 }
Esempio n. 14
0
        /// <summary>
        ///
        /// </summary>
        /// <returns>
        /// returns a hashtable containing 2 keys.
        /// 1. expire-items
        /// 2. resync-items
        /// against these 2, associated cache keys are returned.
        /// </returns>
        internal IDictionary GetExpiredKeys()
        {
            ClusteredArrayList sqlKeyList = _sqlConPool.GetExpiredKeys();

            sqlKeyList.AddRange(_oledbConPool.GetExpiredKeys());

            if (sqlKeyList != null && sqlKeyList.Count > 0)
            {
                HashVector         cacheKeyList = new HashVector();
                ClusteredArrayList expire       = new ClusteredArrayList();
                ClusteredArrayList resync       = new ClusteredArrayList();

                IEnumerator ie = sqlKeyList.GetEnumerator();
                lock (_dbKeysMappingTbl.SyncRoot)
                {
                    while (ie.MoveNext())
                    {
                        if (_dbKeysMappingTbl.Contains(ie.Current))
                        {
                            DependencyInformation depInfo = _dbKeysMappingTbl[ie.Current] as DependencyInformation;
                            if (depInfo != null)
                            {
                                if (depInfo.Hint.NeedsReSync)
                                {
                                    resync.Add(depInfo.CacheKey);
                                }
                                else
                                {
                                    expire.Add(depInfo.CacheKey);
                                }
                            }
                        }
                    }

                    cacheKeyList["expire-items"] = expire;
                    cacheKeyList["resync-items"] = resync;
                    return(cacheKeyList);
                }
            }

            return(new HashVector());
        }
Esempio n. 15
0
        internal static IEnumerable <NodeIndex> GetOverwrites(BasicTransformContext context, IndexedGraph dependencyGraph, NodeIndex writer,
                                                              List <IStatement> nodes, Dictionary <IStatement, int> indexOfNode)
        {
            IStatement            ist = nodes[writer];
            DependencyInformation di  = context.InputAttributes.Get <DependencyInformation>(ist);

            if (di == null)
            {
                context.Error("Dependency information not found for statement: " + ist);
                di = new DependencyInformation();
            }
            foreach (IStatement previousWriteStmt in di.Overwrites)
            {
                NodeIndex previousWriter = indexOfNode[previousWriteStmt];
                if (previousWriter < writer)
                {
                    yield return(previousWriter);
                }
            }
        }
Esempio n. 16
0
        protected void AddEdges(GraphWriter g, IStatement ist, Stage stage)
        {
            Node nd = GetNodeForStatement(ist, stage);

            if (nd == null)
            {
                return;
            }
            DependencyInformation di = context.InputAttributes.Get <DependencyInformation>(ist);

            if (di == null)
            {
                return;
            }
            AddDependencyEdges(g, nd, di, Stage.Initialisation, stage);
            if (stage != Stage.Initialisation)
            {
                AddDependencyEdges(g, nd, di, Stage.Update, stage);
            }
        }
Esempio n. 17
0
 protected void AddDependencyEdges(GraphWriter g, Node nd, DependencyInformation di, Stage stage, Stage parentStage)
 {
     foreach (IStatement source in di.GetDependenciesOfType(DependencyType.Dependency | DependencyType.Declaration))
     {
         Node nd2 = GetNodeForStatement(source, stage);
         if (nd2 == null)
         {
             continue;
         }
         bool backwards = ((int)nd.UserData) < ((int)nd2.UserData);
         //Console.WriteLine("stage=" + stage + " " + nd.UserData + " " + nd2.UserData);
         Edge e;
         if (backwards)
         {
             e         = g.AddEdge(nd.ID, nd2.ID);
             e.Color   = Color.Red;
             e.Reverse = true;
         }
         else
         {
             e = g.AddEdge(nd2.ID, nd.ID);
             if (parentStage != stage)
             {
                 e.Color = Color.LightGray;
             }
         }
         if (di.HasDependency(DependencyType.Trigger, source))
         {
             e.Width = 2;
         }
         if (di.HasDependency(DependencyType.Fresh, source))
         {
             e.Style = EdgeStyle.Dashed;
         }
         if (di.HasDependency(DependencyType.Cancels, source))
         {
             e.Color = Color.LightGray;
         }
     }
     //e.Label = StatementLabel(ist);            e.Label.FontSize = 8;
 }
Esempio n. 18
0
        public DependencyGraph2(BasicTransformContext context,
                                IEnumerable <IStatement> inputs,
                                BackEdgeHandling backEdgeHandling,
                                Action <IWhileStatement> beginWhile,
                                Action <IWhileStatement> endWhile,
                                Action <IConditionStatement> beginFirstIterPost,
                                Action <IConditionStatement> endFirstIterPost,
                                Action <IStatement, NodeIndex> action)
        {
            Set <NodeIndex> nodesInCurrentWhile = new Set <EdgeIndex>();
            int             whileDepth          = 0;

            // create a dependency graph where while loops are flattened (the while loops themselves are not nodes)
            // the graph will only contain read-after-write and write-after-alloc dependencies for now
            // add write-after-read dependencies
            isWriteAfterRead = dependencyGraph.CreateEdgeData(false);
            DeadCodeTransform.ForEachStatement(inputs,
                                               delegate(IWhileStatement iws)
            {
                beginWhile(iws);
                nodesInCurrentWhile.Clear();
                whileDepth++;
            },
                                               delegate(IWhileStatement iws)
            {
                // all duplicates in a while loop should share all targets
                foreach (KeyValuePair <IStatement, Set <NodeIndex> > entry in duplicates)
                {
                    IStatement ist          = entry.Key;
                    Set <NodeIndex> set     = entry.Value;
                    Set <NodeIndex> targets = new Set <EdgeIndex>();
                    // collect all targets in the while loop
                    foreach (NodeIndex node in set)
                    {
                        foreach (NodeIndex target in dependencyGraph.TargetsOf(node))
                        {
                            if (nodesInCurrentWhile.Contains(target))
                            {
                                targets.Add(target);
                            }
                        }
                    }
                    Set <NodeIndex> backEdgeTargets = null;
                    if (!backEdges.TryGetValue(ist, out backEdgeTargets))
                    {
                        backEdgeTargets = new Set <EdgeIndex>();
                        backEdges[ist]  = backEdgeTargets;
                    }
                    // add all targets to all duplicates in the loop
                    foreach (NodeIndex node in set)
                    {
                        if (!nodesInCurrentWhile.Contains(node))
                        {
                            continue;
                        }
                        foreach (NodeIndex target in targets)
                        {
                            if (!dependencyGraph.ContainsEdge(node, target))
                            {
                                if (backEdgeHandling == BackEdgeHandling.Include)
                                {
                                    dependencyGraph.AddEdge(node, target);
                                }
                                else if (backEdgeHandling == BackEdgeHandling.Reverse)
                                {
                                    if (!dependencyGraph.ContainsEdge(target, node))
                                    {
                                        dependencyGraph.AddEdge(target, node);
                                    }
                                }
                                if (target < node)
                                {
                                    if (backEdgeTargets == null && !backEdges.TryGetValue(ist, out backEdgeTargets))
                                    {
                                        backEdgeTargets = new Set <EdgeIndex>();
                                        backEdges[ist]  = backEdgeTargets;
                                    }
                                    backEdgeTargets.Add(target);
                                }
                            }
                        }
                    }
                }
                endWhile(iws);
                whileDepth--;
            },
                                               beginFirstIterPost,
                                               endFirstIterPost,
                                               delegate(IStatement ist)
            {
                DependencyInformation di = context.InputAttributes.Get <DependencyInformation>(ist);
                if (di == null)
                {
                    context.Error("Dependency information not found for statement: " + ist);
                    di = new DependencyInformation();
                }
                NodeIndex targetIndex = dependencyGraph.AddNode();
                Set <NodeIndex> backEdgeTargets;
                Set <NodeIndex> sources = new Set <NodeIndex>();                                  // for fast checking of duplicate sources
                foreach (IStatement source in
                         di.GetDependenciesOfType(DependencyType.Dependency | DependencyType.Declaration))
                {
                    int sourceIndex;
                    // we assume that the statements are already ordered properly to respect dependencies.
                    // if the source is not in indexOfNode, then it must be a cyclic dependency in this while loop.
                    if (indexOfNode.TryGetValue(source, out sourceIndex))
                    {
                        if (!sources.Contains(sourceIndex))
                        {
                            sources.Add(sourceIndex);
                            EdgeIndex edge = dependencyGraph.AddEdge(sourceIndex, targetIndex);
                        }
                    }
                    else
                    {
                        sourceIndex = -1;
                    }
                    if (sourceIndex == -1)
                    {
                        // add a back edge
                        if (!backEdges.TryGetValue(source, out backEdgeTargets))
                        {
                            backEdgeTargets   = new Set <EdgeIndex>();
                            backEdges[source] = backEdgeTargets;
                        }
                        backEdgeTargets.Add(targetIndex);
                        // add a dependency on the initializers of source
                        Stack <IStatement> todo = new Stack <IStatement>();
                        todo.Push(source);
                        while (todo.Count > 0)
                        {
                            IStatement source2        = todo.Pop();
                            DependencyInformation di2 = context.InputAttributes.Get <DependencyInformation>(source2);
                            if (di2 == null)
                            {
                                context.Error("Dependency information not found for statement: " + source2);
                                continue;
                            }
                            foreach (IStatement init in di2.Overwrites)
                            {
                                int initIndex;
                                if (indexOfNode.TryGetValue(init, out initIndex))
                                {
                                    if (!sources.Contains(initIndex))
                                    {
                                        sources.Add(initIndex);
                                        EdgeIndex edge = dependencyGraph.AddEdge(initIndex, targetIndex);
                                    }
                                }
                                else
                                {
                                    todo.Push(init);
                                }
                            }
                        }
                    }
                }
                if (indexOfNode.ContainsKey(ist))
                {
                    Set <int> set;
                    if (!duplicates.TryGetValue(ist, out set))
                    {
                        set             = new Set <int>();
                        duplicates[ist] = set;
                        set.Add(indexOfNode[ist]);
                    }
                    set.Add(targetIndex);
                }
                // the same statement may appear multiple times.  when looking up indexOfNode, we want to use the last occurrence of the statement.
                indexOfNode[ist] = targetIndex;                                    // must do this at the end, in case the stmt depends on a previous occurrence of itself
                nodesInCurrentWhile.Add(targetIndex);
                nodes.Add(ist);
                if (backEdgeHandling != BackEdgeHandling.Ignore && backEdges.TryGetValue(ist, out backEdgeTargets))
                {
                    // now that ist has an index, we can fill in the back edges
                    foreach (NodeIndex node in backEdgeTargets)
                    {
                        if (backEdgeHandling == BackEdgeHandling.Include)
                        {
                            if (dependencyGraph.ContainsEdge(targetIndex, node))
                            {
                                throw new Exception("Internal: back edge already present");
                            }
                            dependencyGraph.AddEdge(targetIndex, node);
                        }
                        else
                        {
                            // make a new edge, even if one exists.
                            EdgeIndex edge         = dependencyGraph.AddEdge(node, targetIndex);
                            isWriteAfterRead[edge] = true;
                        }
                    }
                }
                action(ist, targetIndex);
            });
            if (string.Empty.Length > 0)
            {
                // loop statements in their original order
                foreach (NodeIndex target in dependencyGraph.Nodes)
                {
                    IStatement ist = nodes[target];
                    if (ist is IWhileStatement)
                    {
                        continue;
                    }
                    foreach (NodeIndex source in GetPreviousReaders(context, dependencyGraph, target, nodes, indexOfNode).ToReadOnlyList())
                    {
                        if (source > target)
                        {
                            throw new Exception("Internal: source statement follows target");
                        }
                        // make a new edge, even if one exists.
                        EdgeIndex edge = dependencyGraph.AddEdge(source, target);
                        isWriteAfterRead[edge] = true;
                    }
                }
            }
            isWriteAfterWrite = dependencyGraph.CreateEdgeData(false);
            // loop statements in their original order
            foreach (NodeIndex target in dependencyGraph.Nodes)
            {
                IStatement ist = nodes[target];
                if (ist is IWhileStatement)
                {
                    continue;
                }

                foreach (NodeIndex source in GetOverwrites(context, dependencyGraph, target, nodes, indexOfNode).ToReadOnlyList())
                {
                    if (source > target)
                    {
                        throw new Exception("Internal: source statement follows target");
                    }
                    if (dependencyGraph.ContainsEdge(source, target))
                    {
                        foreach (EdgeIndex edge in dependencyGraph.EdgesLinking(source, target))
                        {
                            isWriteAfterWrite[edge] = true;
                        }
                    }
                    else
                    {
                        EdgeIndex edge = dependencyGraph.AddEdge(source, target);
                        isWriteAfterWrite[edge] = true;
                    }
                }
            }

            dependencyGraph.NodeCountIsConstant = true;
            dependencyGraph.IsReadOnly          = true;
            for (int targetIndex = 0; targetIndex < dependencyGraph.Nodes.Count; targetIndex++)
            {
                IStatement            ist = nodes[targetIndex];
                DependencyInformation di  = context.InputAttributes.Get <DependencyInformation>(ist);
                if (di == null)
                {
                    continue;
                }
                if (di.IsOutput)
                {
                    outputNodes.Add(targetIndex);
                }
            }
        }
        protected override IStatement ConvertWhile(IWhileStatement iws)
        {
            bool wasInWhileLoop = this.inWhileLoop;

            if (!wasInWhileLoop)
            {
                // collect all statements in the body of this loop (and any nested loops).
                DeadCodeTransform.ForEachStatement(iws.Body.Statements,
                                                   _ =>
                {
                }, _ =>
                {
                },
                                                   _ =>
                {
                }, _ =>
                {
                },
                                                   ist =>
                {
                    visitedStatements.Add(ist);
                });
                // collect all IncrementStatement attributes in the body of this loop (and any nested loops).
                DeadCodeTransform.ForEachStatement(iws.Body.Statements,
                                                   _ =>
                {
                }, _ =>
                {
                },
                                                   _ =>
                {
                }, _ =>
                {
                },
                                                   ist =>
                {
                    var incrementStatement = context.GetAttribute <IncrementStatement>(ist);
                    if (incrementStatement != null)
                    {
                        DependencyInformation di = context.GetAttribute <DependencyInformation>(ist);
                        if (di != null && !di.GetDependenciesOfType(DependencyType.Cancels).All(visitedStatements.Contains))
                        {
                            // Remove increment statements whose Cancels input is not available, implying that there is no purpose in carrying out the increment.
                            // This happens because IterationTransform ignores Cancels edges.
                            replacements[ist] = null;
                        }
                        else
                        {
                            incrementStatements.Add(incrementStatement);
                        }
                    }
                });
                ancestorIndexOfWhile = context.Depth - 1;
            }
            this.inWhileLoop = true;
            var ws = base.ConvertWhile(iws);

            this.inWhileLoop = wasInWhileLoop;
            if (!wasInWhileLoop)
            {
                incrementStatements.Clear();
            }
            return(ws);
        }
Esempio n. 20
0
        private List <IStatement> Schedule(DependencyGraph g, IList <IStatement> stmts, bool createFirstIterPostBlocks)
        {
            List <IStatement>     output       = new List <IStatement>();
            List <StatementBlock> blocks       = new List <StatementBlock>();
            List <NodeIndex>      currentBlock = null;
            DirectedGraphFilter <NodeIndex, EdgeIndex> graph2 = new DirectedGraphFilter <NodeIndex, EdgeIndex>(g.dependencyGraph, edge => !g.isDeleted[edge]);
            StrongComponents2 <NodeIndex> scc = new StrongComponents2 <NodeIndex>(graph2.SourcesOf, graph2);

            scc.AddNode        += delegate(NodeIndex node) { currentBlock.Add(node); };
            scc.BeginComponent += delegate() { currentBlock = new List <int>(); };
            scc.EndComponent   += delegate() {
                bool isCyclic = false;
                if (currentBlock.Count == 1)
                {
                    NodeIndex node = currentBlock[0];
                    foreach (NodeIndex source in graph2.SourcesOf(node))
                    {
                        if (source == node)
                        {
                            isCyclic = true;
                            break;
                        }
                    }
                }
                else
                {
                    isCyclic = true;
                }
                if (isCyclic)
                {
                    blocks.Add(new Loop()
                    {
                        indices = currentBlock
                    });
                }
                else
                {
                    blocks.Add(new StraightLine()
                    {
                        indices = currentBlock
                    });
                }
            };
            scc.SearchFrom(graph2.Nodes);
            //scc.SearchFrom(g.outputNodes);

            bool check = false;

            if (check)
            {
                // check that there are no edges from a later component to an earlier component
                Set <NodeIndex> earlierNodes = new Set <int>();
                foreach (StatementBlock block in blocks)
                {
                    earlierNodes.AddRange(block.indices);
                    foreach (NodeIndex node in block.indices)
                    {
                        foreach (NodeIndex source in graph2.SourcesOf(node))
                        {
                            if (!earlierNodes.Contains(source))
                            {
                                Console.WriteLine(g.NodeToString(node) + Environment.NewLine + "   depends on later node " + g.NodeToString(source));
                                Error("Internal error: Strong components are not ordered properly");
                            }
                        }
                    }
                }
            }

            Set <NodeIndex> nodesToMove = new Set <NodeIndex>();
            Dictionary <Loop, IBlockStatement> firstIterPostprocessing = null;

            if (createFirstIterPostBlocks)
            {
                firstIterPostprocessing = GetFirstIterPostprocessing(blocks, graph2, stmts, nodesToMove);
            }
            IVariableDeclaration iteration = Builder.VarDecl("iteration", typeof(int));

            IndexedProperty <NodeIndex, bool> isUniform = graph2.CreateNodeData <bool>(true);

            foreach (StatementBlock block in blocks)
            {
                if (block is Loop)
                {
                    foreach (NodeIndex i in block.indices)
                    {
                        isUniform[i] = false;
                    }
                    IWhileStatement    ws        = Builder.WhileStmt(Builder.LiteralExpr(true));
                    IList <IStatement> whileBody = ws.Body.Statements;

                    if (ContainsIterationStatement(stmts, block.indices))
                    {
                        List <IStatement> nodes = new List <IStatement>();
                        foreach (NodeIndex i in block.indices)
                        {
                            IStatement ist = stmts[i];
                            if (!context.InputAttributes.Has <IterationStatement>(ist))
                            {
                                nodes.Add(ist);
                            }
                        }
                        // build a new dependency graph with the dummy iteration statement removed
                        DependencyGraph   g2  = new DependencyGraph(context, nodes, ignoreMissingNodes: true, ignoreRequirements: true);
                        List <IStatement> sc3 = Schedule(g2, nodes, false);
                        if (sc3.Count == 1 && sc3[0] is IWhileStatement)
                        {
                            ws = (IWhileStatement)sc3[0];
                        }
                        else
                        {
                            // The statements in the outer loop are not strongly connected.
                            // Since we want the next transform to only process strong components,
                            // we mark the outer while loop as DoNotSchedule, leaving only the
                            // inner while loops to be scheduled.
                            // add all statements in sc3 to whileBody, but remove while loops around a single statement.
                            foreach (IStatement ist in sc3)
                            {
                                if (ist is IWhileStatement)
                                {
                                    IWhileStatement iws2 = (IWhileStatement)ist;
                                    if (iws2.Body.Statements.Count == 1)
                                    {
                                        whileBody.AddRange(iws2.Body.Statements);
                                        continue;
                                    }
                                }
                                whileBody.Add(ist);
                            }
                            context.OutputAttributes.Set(ws, new DoNotSchedule());
                        }
                    }
                    else // !ContainsIterationStatement
                    {
                        foreach (NodeIndex i in block.indices)
                        {
                            IStatement st = stmts[i];
                            whileBody.Add(st);
                            DependencyInformation di = context.InputAttributes.Get <DependencyInformation>(st);
                            di.AddClones(clonesOfStatement);
                        }
                        RegisterUnchangedStatements(whileBody);
                    }
                    Loop loop = (Loop)block;
                    if (firstIterPostprocessing != null && firstIterPostprocessing.ContainsKey(loop))
                    {
                        var thenBlock         = firstIterPostprocessing[loop];
                        var iterIsZero        = Builder.BinaryExpr(BinaryOperator.ValueEquality, Builder.VarRefExpr(iteration), Builder.LiteralExpr(0));
                        var firstIterPostStmt = Builder.CondStmt(iterIsZero, thenBlock);
                        context.OutputAttributes.Set(firstIterPostStmt, new FirstIterationPostProcessingBlock());
                        whileBody.Add(firstIterPostStmt);
                    }
                    output.Add(ws);
                }
                else
                {
                    // not cyclic
                    foreach (NodeIndex i in block.indices)
                    {
                        IStatement st = stmts[i];
                        if (!nodesToMove.Contains(i))
                        {
                            output.Add(st);
                            DependencyInformation di = context.InputAttributes.Get <DependencyInformation>(st);
                            di.AddClones(clonesOfStatement);
                        }
                        isUniform[i] = g.IsUniform(i, source => !isUniform[source]);
                        if (isUniform[i] != g.isUniform[i])
                        {
                            Assert.IsTrue(isUniform[i]);
                            g.isUniform[i] = isUniform[i];
                            DependencyInformation di = context.InputAttributes.Get <DependencyInformation>(st);
                            di.IsUniform = isUniform[i];
                        }
                        // mark sources of output statements (for SchedulingTransform)
                        if (g.outputNodes.Contains(i))
                        {
                            foreach (NodeIndex source in graph2.SourcesOf(i))
                            {
                                IStatement sourceSt = stmts[source];
                                if (!context.InputAttributes.Has <OutputSource>(sourceSt))
                                {
                                    context.OutputAttributes.Set(sourceSt, new OutputSource());
                                }
                            }
                        }
                    }
                }
            }
            return(output);
        }
        /// <summary>
        /// Update the dependency information of all statements, assuming that the original statements have been permuted and duplicated, but not transformed.
        /// </summary>
        /// <param name="outputs"></param>
        private void PostProcessDependencies(ICollection <IStatement> outputs)
        {
            Dictionary <IStatement, int> indexOfStatement = new Dictionary <IStatement, NodeIndex>(ReferenceEqualityComparer <IStatement> .Instance);

            if (clonesOfStatement.Count == 0)
            {
                return;
            }
            DeadCodeTransform.ForEachStatement(outputs,
                                               _ => { },
                                               _ => { },
                                               _ => { },
                                               _ => { },
                                               ist =>
            {
                DependencyInformation di = context.InputAttributes.Get <DependencyInformation>(ist);
                if (di != null)
                {
                    // must make a clone since this statement may appear in multiple contexts
                    DependencyInformation di2 = (DependencyInformation)di.Clone();
                    di2.AddClones(clonesOfStatement);
                    IStatement originalStatement;
                    originalStatementOfClone.TryGetValue(ist, out originalStatement);
                    // originalStatement is non-null iff ist is a clone
                    IEnumerable <IStatement> clones;
                    if (clonesOfStatement.TryGetValue(originalStatement ?? ist, out clones))
                    {
                        // clones become Overwrites
                        foreach (var clone in clones)
                        {
                            di2.Add(DependencyType.Overwrite, clone);
                        }
                        if (originalStatement != null)
                        {
                            di2.Add(DependencyType.Overwrite, originalStatement);
                        }
                    }
                    // keep only the most recent overwrite that is not an allocation, and all overwrites that are allocations.
                    IStatement mostRecentWriter   = null;
                    int mostRecentWriterIndex     = 0;
                    List <IStatement> allocations = new List <IStatement>();
                    foreach (var writer in di2.Overwrites)
                    {
                        int index;
                        indexOfStatement.TryGetValue(writer, out index);
                        if (index > mostRecentWriterIndex)
                        {
                            mostRecentWriterIndex = index;
                            mostRecentWriter      = writer;
                        }
                        if (di2.HasDependency(DependencyType.Declaration, writer))
                        {
                            allocations.Add(writer);
                        }
                    }
                    di2.Remove(DependencyType.Overwrite);
                    // all allocations must remain as Overwrites
                    foreach (var dep in allocations)
                    {
                        di2.Add(DependencyType.Overwrite, dep);
                    }
                    if (mostRecentWriter != null)
                    {
                        di2.Add(DependencyType.Overwrite, mostRecentWriter);
                    }
                    context.OutputAttributes.Remove <DependencyInformation>(ist);
                    context.OutputAttributes.Set(ist, di2);
                }
                indexOfStatement[ist] = indexOfStatement.Count + 1;
            });
        }
 void ProcessStatements(IList <IStatement> outputs, IList <IStatement> outputDecls, IList <IStatement> inputs, Dictionary <IStatement, IStatement> replacements)
 {
     for (int i = 0; i < inputs.Count; i++)
     {
         IStatement ist = inputs[i];
         if (ist is IWhileStatement)
         {
             IWhileStatement iws           = (IWhileStatement)ist;
             IWhileStatement ws            = Builder.WhileStmt(iws);
             bool            doNotSchedule = context.InputAttributes.Has <DoNotSchedule>(iws);
             if (doNotSchedule)
             {
                 // iws may contain nested while loops
                 // TODO: make sure the new decls go in the right place
                 ProcessStatements(ws.Body.Statements, outputDecls, iws.Body.Statements, replacements);
             }
             else
             {
                 IReadOnlyList <IStatement> inputStmts = (IReadOnlyList <IStatement>)iws.Body.Statements;
                 IStatement      firstIterPostBlock    = ForwardBackwardTransform.ExtractFirstIterationPostProcessingBlock(context, ref inputStmts);
                 DependencyGraph g = new DependencyGraph(context, inputStmts, ignoreMissingNodes: true, ignoreRequirements: true);
                 // look for cycles of initialized nodes and insert clones as needed
                 Set <NodeIndex> nodesToClone = GetNodesToClone(g, g.dependencyGraph.Nodes);
                 for (int node = 0; node < inputStmts.Count; node++)
                 {
                     IStatement st = inputStmts[node];
                     if (nodesToClone.Contains(node))
                     {
                         cloneDecls.Clear();
                         cloneUpdates.Clear();
                         containers.Clear();
                         IStatement newStmt   = ConvertStatement(st);
                         IStatement declStmt  = cloneDecls[0];
                         IStatement setToStmt = cloneUpdates[0];
                         outputDecls.AddRange(cloneDecls);
                         DependencyInformation diNew = (DependencyInformation)context.InputAttributes.Get <DependencyInformation>(newStmt).Clone();
                         context.OutputAttributes.Remove <DependencyInformation>(newStmt);
                         context.OutputAttributes.Set(newStmt, diNew);
                         DependencyInformation diSet = new DependencyInformation();
                         diSet.Add(DependencyType.Dependency | DependencyType.Requirement, newStmt);
                         context.OutputAttributes.Set(setToStmt, diSet);
                         DependencyInformation diDecl = new DependencyInformation();
                         context.OutputAttributes.Set(declStmt, diDecl);
                         foreach (IStatement writer in diNew.Overwrites)
                         {
                             diDecl.Add(DependencyType.Dependency, writer);
                             diSet.Add(DependencyType.Overwrite, writer);
                         }
                         diNew.Remove(DependencyType.Overwrite);
                         diNew.Add(DependencyType.Declaration | DependencyType.Dependency | DependencyType.Overwrite, declStmt);
                         if (loopMergingInfo != null)
                         {
                             // update loopMergingInfo with the new statement
                             int oldNode = loopMergingInfo.GetIndexOf(st);
                             int newNode = loopMergingInfo.AddNode(newStmt);
                             loopMergingInfo.InheritSourceConflicts(newNode, oldNode);
                             int setToNode = loopMergingInfo.AddNode(setToStmt);
                             loopMergingInfo.InheritTargetConflicts(setToNode, oldNode);
                             int declNode = loopMergingInfo.AddNode(declStmt);
                         }
                         replacements[st] = setToStmt;
                         context.InputAttributes.CopyObjectAttributesTo <InitialiseBackward>(st, context.OutputAttributes, setToStmt);
                         st = newStmt;
                         ws.Body.Statements.AddRange(cloneUpdates);
                     }
                     else
                     {
                         RegisterUnchangedStatement(st);
                     }
                     ws.Body.Statements.Add(st);
                 }
                 if (firstIterPostBlock != null)
                 {
                     ws.Body.Statements.Add(firstIterPostBlock);
                 }
             }
             context.InputAttributes.CopyObjectAttributesTo(iws, context.OutputAttributes, ws);
             ist = ws;
         }
         else
         {
             RegisterUnchangedStatement(ist);
         }
         outputs.Add(ist);
     }
 }
Esempio n. 23
0
        protected IList <IStatement> Schedule(IReadOnlyList <IStatement> isc)
        {
            DependencyGraph g = new DependencyGraph(context, isc, ignoreMissingNodes: false, ignoreRequirements: true, readAfterWriteOnly: true);

            // The uniform statements must be removed first, before doing the search backward from outputs.
            // This is important because it allows dependencies of uniform statements to be pruned.
            // For example, suppose A requires B and C, B is uniform.  This means that A is uniform and A will be pruned.
            // As a result, C doesn't need to be computed (even if it might be non-uniform).
            if (PruneUniformStmts)
            {
                g.PropagateUniformNodes();
            }

            // Propagate DependsOnIteration
            DependsOnIteration           attr    = null;
            DepthFirstSearch <NodeIndex> dfsIter = new DepthFirstSearch <EdgeIndex>(g.dependencyGraph.TargetsOf, g.nodeData);

            dfsIter.DiscoverNode += delegate(NodeIndex node) {
                if (!context.OutputAttributes.Has <DependsOnIteration>(isc[node]))
                {
                    context.OutputAttributes.Set(isc[node], attr);
                }
            };
            foreach (NodeIndex node in g.dependencyGraph.Nodes)
            {
                attr = context.GetAttribute <DependsOnIteration>(isc[node]);
                if (attr != null)
                {
                    dfsIter.SearchFrom(node);
                }
            }

            // search backward from the outputs to find statements that are relevant.
            DepthFirstSearch <NodeIndex> dfs = new DepthFirstSearch <NodeIndex>(
                PruneUniformStmts ? (Converter <int, IEnumerable <int> >)g.SourcesNeededForOutput : g.dependencyGraph.SourcesOf,
                g.nodeData);

            dfs.SearchFrom(g.outputNodes);
            List <NodeIndex> schedule = new List <NodeIndex>();

            foreach (NodeIndex node in g.dependencyGraph.Nodes)
            {
                // any statement found in the search is relevant.  other statements are pruned.
                if (dfs.IsVisited[node] == VisitState.Finished)
                {
                    schedule.Add(node);
                }
            }

            if (debug)
            {
                var             itdOut = context.FindOutputForAncestor <ITypeDeclaration, ITypeDeclaration>();
                IBlockStatement block  = Builder.BlockStmt();
                foreach (var line in StringUtil.Lines(g.dependencyGraph.ToString()))
                {
                    block.Statements.Add(Builder.CommentStmt(line));
                }
                foreach (NodeIndex node in g.dependencyGraph.Nodes)
                {
                    block.Statements.Add(Builder.CommentStmt($"{node} {isc[node]}"));
                }
                context.OutputAttributes.Add(itdOut, new DebugInfo()
                {
                    Transform = this,
                    Name      = "Graph",
                    Value     = block
                });
            }

            if (PruneUniformStmts)
            {
                // When statements are pruned from the code, they must also be pruned from the DependencyInformation attributes of all other statements that might refer to them.
                Dictionary <IStatement, IStatement> replacements = new Dictionary <IStatement, IStatement>(ReferenceEqualityComparer <IStatement> .Instance);
                foreach (NodeIndex targetIndex in g.dependencyGraph.Nodes)
                {
                    if (g.isUniform[targetIndex])
                    {
                        IStatement            ist = isc[targetIndex];
                        DependencyInformation di  = context.InputAttributes.Get <DependencyInformation>(ist);
                        // this is needed for detection of non-uniform initializers
                        di.IsUniform = true;
                    }
                    if (g.isUniform[targetIndex] && !g.isEssential[targetIndex])
                    {
                        NodeIndex source = g.FindInitializer(targetIndex);
                        if (source != targetIndex)
                        {
                            IStatement target      = isc[targetIndex];
                            IStatement replacement = isc[source];
                            replacements[target] = replacement;
                        }
                    }
                }
                foreach (NodeIndex targetIndex in schedule)
                {
                    IStatement            target = isc[targetIndex];
                    DependencyInformation di     = context.InputAttributes.Get <DependencyInformation>(target);
                    di.Replace(replacements);
                }
            }

            IList <IStatement> sc = Builder.StmtCollection();

            foreach (NodeIndex i in schedule)
            {
                IStatement st = isc[i];
                sc.Add(st);
            }
            return(sc);
        }