Пример #1
0
        protected void AddUsage(IExpression expr, bool isWrite)
        {
            bool anyIndexIsPartitioned = (expr is IArrayIndexerExpression) &&
                                         Recognizer.GetIndices(expr).Any(bracket => bracket.Any(index => Recognizer.GetVariables(index).Any(context.InputAttributes.Has <Partitioned>)));
            object decl = Recognizer.GetDeclaration(expr);

            if (decl == null || (!anyIndexIsPartitioned && context.InputAttributes.Has <LocalTransform.DoNotUseLocal>(decl)))
            {
                return;
            }
            if (containerInfos.Count == 0)
            {
                return;
            }
            ContainerInfo containerInfo = containerInfos.Peek();
            UsageInfo     usageInfo;

            if (!containerInfo.usageInfoOfVariable.TryGetValue(decl, out usageInfo))
            {
                usageInfo = new UsageInfo();
                containerInfo.usageInfoOfVariable[decl] = usageInfo;
            }
            LocalInfo info;

            if (!usageInfo.localInfos.TryGetValue(expr, out info))
            {
                info = new LocalInfo();
                info.minWriteDepth           = int.MaxValue;
                info.minReadBeforeWriteDepth = int.MaxValue;
                // this assignment is not needed since we must have depth < info.minWriteDepth
                //info.hasReadBeforeWrite = !isWrite;
                usageInfo.localInfos[expr] = info;
            }
            int depth = Recognizer.GetIndexingDepth(expr);

            if (isWrite)
            {
                info.hasWrite      = true;
                info.minWriteDepth = System.Math.Min(info.minWriteDepth, depth);
            }
            else if (depth < info.minWriteDepth)
            {
                info.hasReadBeforeWrite      = true;
                info.minReadBeforeWriteDepth = System.Math.Min(info.minReadBeforeWriteDepth, depth);
            }
            info.count++;
            if (info.containingStatements == null)
            {
                info.containingStatements = new HashSet <IStatement>(openContainers, ReferenceEqualityComparer <IStatement> .Instance);
                info.containers           = GetContainers();
            }
            else
            {
                info.containingStatements.IntersectWith(openContainers);
                info.containers = Containers.Intersect(info.containers, GetContainers(), allowBrokenLoops: true, ignoreLoopDirection: true);
            }
        }
Пример #2
0
 public void Add(LocalInfo localInfo)
 {
     this.hasWrite                = this.hasWrite || localInfo.hasWrite;
     this.minWriteDepth           = System.Math.Min(this.minWriteDepth, localInfo.minWriteDepth);
     this.hasReadBeforeWrite      = this.hasReadBeforeWrite || localInfo.hasReadBeforeWrite;
     this.minReadBeforeWriteDepth = System.Math.Min(this.minReadBeforeWriteDepth, localInfo.minReadBeforeWriteDepth);
     this.appearsInNestedLoop     = this.appearsInNestedLoop || localInfo.appearsInNestedLoop;
     this.count += localInfo.count;
     this.containingStatements.IntersectWith(localInfo.containingStatements);
     this.containers = Containers.Intersect(this.containers, localInfo.containers, allowBrokenLoops: true, ignoreLoopDirection: true);
 }
Пример #3
0
        private void RegisterDepth(IExpression expr, bool isDef)
        {
            if (Recognizer.IsBeingIndexed(context))
            {
                return;
            }
            int depth = Recognizer.GetIndexingDepth(expr);
            IVariableDeclaration baseVar = Recognizer.GetVariableDeclaration(expr);

            // If not an indexed variable reference, skip it (e.g. an indexed argument reference)
            if (baseVar == null)
            {
                return;
            }
            // If the variable is not stochastic, skip it
            if (!CodeRecognizer.IsStochastic(context, baseVar))
            {
                return;
            }
            ChannelInfo ci = context.InputAttributes.Get <ChannelInfo>(baseVar);

            if (ci != null && ci.IsMarginal)
            {
                return;
            }
            DepthInfo depthInfo;

            if (!depthInfos.TryGetValue(baseVar, out depthInfo))
            {
                depthInfo           = new DepthInfo();
                depthInfos[baseVar] = depthInfo;
            }
            if (isDef)
            {
                depthInfo.definitionDepth = depth;
                return;
            }
            depthInfo.useCount++;
            if (depth < depthInfo.minDepth)
            {
                depthInfo.minDepth = depth;
            }
            int literalIndexingDepth = 0;

            foreach (var bracket in Recognizer.GetIndices(expr))
            {
                if (!bracket.All(index => index is ILiteralExpression))
                {
                    break;
                }
                literalIndexingDepth++;
            }
            IndexInfo info;

            if (depthInfo.indexInfoOfDepth.TryGetValue(depth, out info))
            {
                Containers containers = new Containers(context);
                info.containers           = Containers.Intersect(info.containers, containers);
                info.literalIndexingDepth = System.Math.Min(info.literalIndexingDepth, literalIndexingDepth);
            }
            else
            {
                info                              = new IndexInfo();
                info.containers                   = new Containers(context);
                info.literalIndexingDepth         = literalIndexingDepth;
                depthInfo.indexInfoOfDepth[depth] = info;
            }
        }
        protected override IExpression ConvertArrayIndexer(IArrayIndexerExpression iaie)
        {
            bool isDef = Recognizer.IsBeingMutated(context, iaie);

            if (isDef)
            {
                // do not clone the lhs of an array create assignment.
                IAssignExpression assignExpr = context.FindAncestor <IAssignExpression>();
                if (assignExpr.Expression is IArrayCreateExpression)
                {
                    return(iaie);
                }
            }
            base.ConvertArrayIndexer(iaie);
            IndexInfo info;

            // TODO: Instead of storing an IndexInfo for each distinct expression, we should try to unify expressions, as in GateAnalysisTransform.
            // For example, we could unify a[0,i] and a[0,0] and use the same clone array for both.
            if (indexInfoOf.TryGetValue(iaie, out info))
            {
                Containers containers = new Containers(context);
                if (info.bindings.Count > 0)
                {
                    List <ConditionBinding> bindings = GetBindings(context, containers.inputs);
                    if (bindings.Count == 0)
                    {
                        info.bindings.Clear();
                    }
                    else
                    {
                        info.bindings.Add(bindings);
                    }
                }
                info.containers = Containers.Intersect(info.containers, containers);
                info.count++;
                if (isDef)
                {
                    info.IsAssignedTo = true;
                }
                return(iaie);
            }
            CheckIndicesAreNotStochastic(iaie.Indices);
            IVariableDeclaration baseVar = Recognizer.GetVariableDeclaration(iaie);

            // If not an indexed variable reference, skip it (e.g. an indexed argument reference)
            if (baseVar == null)
            {
                return(iaie);
            }
            // If the variable is not stochastic, skip it
            if (!CodeRecognizer.IsStochastic(context, baseVar))
            {
                return(iaie);
            }
            // If the indices are all loop variables, skip it
            var  indices        = Recognizer.GetIndices(iaie);
            bool allLoopIndices = indices.All(bracket => bracket.All(indexExpr =>
            {
                if (indexExpr is IVariableReferenceExpression)
                {
                    IVariableReferenceExpression ivre = (IVariableReferenceExpression)indexExpr;
                    return(Recognizer.GetLoopForVariable(context, ivre) != null);
                }
                else
                {
                    return(false);
                }
            }));

            if (allLoopIndices)
            {
                return(iaie);
            }

            info            = new IndexInfo();
            info.containers = new Containers(context);
            List <ConditionBinding> bindings2 = GetBindings(context, info.containers.inputs);

            if (bindings2.Count > 0)
            {
                info.bindings.Add(bindings2);
            }
            info.count        = 1;
            info.IsAssignedTo = isDef;
            indexInfoOf[iaie] = info;
            return(iaie);
        }