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