コード例 #1
0
        protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre)
        {
            bool isDef = Recognizer.IsBeingMutated(context, ivre);

            RegisterDepth(ivre, isDef);
            return(ivre);
        }
コード例 #2
0
 private IExpression GetMessageExpression(IExpression expr, IDictionary <IVariableDeclaration, IVariableDeclaration> msgVars)
 {
     if (expr is IVariableReferenceExpression)
     {
         IVariableReferenceExpression ivre = (IVariableReferenceExpression)expr;
         IVariableDeclaration         ivd  = ivre.Variable.Resolve();
         IVariableDeclaration         msgVar;
         if (msgVars.TryGetValue(ivd, out msgVar))
         {
             return(Builder.VarRefExpr(msgVar));
         }
         else
         {
             return(null);
         }
     }
     else if (expr is IArrayIndexerExpression)
     {
         IArrayIndexerExpression iaie      = (IArrayIndexerExpression)expr;
         IExpression             targetMsg = GetMessageExpression(iaie.Target, msgVars);
         if (targetMsg == null)
         {
             return(null);
         }
         else
         {
             return(Builder.ArrayIndex(targetMsg, iaie.Indices));
         }
     }
     else
     {
         throw new ArgumentException("Unrecognized method argument expression");
     }
 }
コード例 #3
0
        public static Set <IVariableDeclaration> GetConditionedLoopVariables(BasicTransformContext context)
        {
            Set <IVariableDeclaration> loopVars = new Set <IVariableDeclaration>();

            foreach (IConditionStatement ics in context.FindAncestors <IConditionStatement>())
            {
                ConditionBinding binding = new ConditionBinding(ics.Condition);
                if (binding.lhs is IVariableReferenceExpression)
                {
                    IVariableReferenceExpression ivre = (IVariableReferenceExpression)binding.lhs;
                    if (Recognizer.GetLoopForVariable(context, ivre) != null)
                    {
                        loopVars.Add(Recognizer.GetVariableDeclaration(ivre));
                    }
                }
                if (binding.rhs is IVariableReferenceExpression)
                {
                    IVariableReferenceExpression ivre = (IVariableReferenceExpression)binding.rhs;
                    if (Recognizer.GetLoopForVariable(context, ivre) != null)
                    {
                        loopVars.Add(Recognizer.GetVariableDeclaration(ivre));
                    }
                }
            }
            return(loopVars);
        }
コード例 #4
0
        /// <summary>
        /// Converts a variable reference.
        /// </summary>
        /// <param name="ivre"></param>
        /// <returns></returns>
        protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre)
        {
            if (Recognizer.IsBeingMutated(context, ivre))
            {
                return(ivre);
            }
            else if (Recognizer.IsBeingIndexed(context))
            {
                return(ivre);
            }
            IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(ivre);

            if (ivd == null)
            {
                return(ivre);
            }
            VariableToChannelInformation vtci;

            if (usesOfVariable.TryGetValue(ivd, out vtci))
            {
                if (vtci.usageDepth != 0)
                {
                    Error("wrong usageDepth (" + vtci.usageDepth + " instead of 0)");
                }
                return(Builder.ArrayIndex(Builder.VarRefExpr(vtci.usesDecl), Builder.LiteralExpr(GetUseNumber(ivd, vtci))));
            }
            return(ivre);
        }
コード例 #5
0
        protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre)
        {
            foreach (ConditionBinding binding in iterationContext)
            {
                if (binding.lhs.Equals(ivre))
                {
                    return(binding.rhs);
                }
            }
            IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(ivre);
            UnrolledVar          v;

            if (unrolledVars.TryGetValue(ivd, out v))
            {
                Set <ConditionBinding> bindings = new Set <ConditionBinding>();
                foreach (ConditionBinding binding in iterationContext)
                {
                    if (v.loopVars.Contains(binding.lhs))
                    {
                        bindings.Add(binding);
                    }
                }
                if (!v.clones.ContainsKey(bindings))
                {
                    Error(ivre + " not defined in context " + bindings);
                    return(ivre);
                }
                IVariableDeclaration clone = v.clones[bindings];
                return(Builder.VarRefExpr(clone));
            }
            return(ivre);
        }
コード例 #6
0
ファイル: LocalTransform.cs プロジェクト: kant2002/infer
        protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre)
        {
            bool isPartOfLhs = Recognizer.IsBeingMutated(context, ivre);

            AddUsage(ivre, isPartOfLhs);
            return(base.ConvertVariableRefExpr(ivre));
        }
コード例 #7
0
        protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre)
        {
            bool isDef = Recognizer.IsBeingMutated(context, ivre);

            if (isDef)
            {
                return(ivre);
            }
            return(GetClone(ivre));
        }
コード例 #8
0
        /// <summary>
        /// Modify the argument of Infer to be the marginal channel variable i.e. Infer(a) transforms to Infer(a_marginal).
        /// </summary>
        /// <param name="imie"></param>
        /// <returns></returns>
        protected IExpression ConvertInfer(IMethodInvokeExpression imie)
        {
            IVariableReferenceExpression ivre = imie.Arguments[0] as IVariableReferenceExpression;

            if (ivre == null)
            {
                //Error("Argument to Infer() must be a variable reference, was " + imie.Arguments[0] + ".");
                return(imie);
            }
            // Find expression for the marginal of interest
            IVariableDeclaration         ivd  = ivre.Variable.Resolve();
            VariableToChannelInformation vtci = context.InputAttributes.Get <VariableToChannelInformation>(ivd);

            if (vtci == null)
            {
                return(imie);              // The argument is constant
            }
            ExpressionEvaluator  eval      = new ExpressionEvaluator();
            QueryType            query     = (QueryType)eval.Evaluate(imie.Arguments[2]);
            IVariableDeclaration inferDecl = null;

            if (query == QueryTypes.Marginal)
            {
                inferDecl = vtci.marginalChannel.decl;
            }
            else if (query == QueryTypes.Samples)
            {
                inferDecl = vtci.samplesChannel.decl;
            }
            else if (query == QueryTypes.Conditionals)
            {
                inferDecl = vtci.conditionalsChannel.decl;
            }
            else
            {
                return(imie); // Error("Unrecognized query '"+query+"'");
            }
            IMethodInvokeExpression mie = Builder.MethodInvkExpr();

            mie.Method = imie.Method;
            mie.Arguments.Add(Builder.VarRefExpr(inferDecl));
            for (int i = 1; i < imie.Arguments.Count; i++)
            {
                mie.Arguments.Add(imie.Arguments[i]);
            }
            // move the IsInferred attribute to the inferred channel
            context.OutputAttributes.Remove <IsInferred>(ivd);
            if (!context.OutputAttributes.Has <IsInferred>(inferDecl))
            {
                context.OutputAttributes.Set(inferDecl, new IsInferred());
                context.OutputAttributes.Add(inferDecl, new QueryTypeCompilerAttribute(query));
            }
            return(mie);
        }
コード例 #9
0
        /// <summary>
        /// Modify variable references that can be replaced by other variables.
        /// </summary>
        /// <param name="ivre"></param>
        /// <returns></returns>
        protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre)
        {
            // should not convert if on LHS
            IExpression copyExpr = GetCopyExpr(ivre);

            if (copyExpr != null)
            {
                return(copyExpr);
            }
            return(ivre);
        }
コード例 #10
0
        /// <summary>
        /// Modify variable references that can be replaced by other variables.
        /// </summary>
        /// <param name="ivre"></param>
        /// <returns></returns>
        protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre)
        {
            // should not convert if on LHS
            IExpression copyExpr = GetCopyExpr(ivre);

            if (copyExpr != null && CanBeReplacedBy(ivre, copyExpr.GetExpressionType()))
            {
                return(copyExpr);
            }
            else
            {
                return(ivre);
            }
        }
コード例 #11
0
        public override bool Equals(object obj)
        {
            if (this == obj)
            {
                return(true);
            }

            IVariableReferenceExpression expressionRef = obj as IVariableReferenceExpression;

            if (expressionRef == null)
            {
                return(false);
            }
            return(this.Variable.Equals(expressionRef.Variable.Resolve()));
        }
コード例 #12
0
        /// <summary>
        /// Register a use of a variable without indices
        /// </summary>
        /// <param name="ivre"></param>
        /// <returns></returns>
        protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre)
        {
            IExpression expr = base.ConvertVariableRefExpr(ivre);

            if (Recognizer.IsBeingIndexed(context) || Recognizer.IsBeingMutated(context, expr))
            {
                return(expr);
            }
            IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(expr);

            if (usageInfo.TryGetValue(ivd, out UsageInfo info))
            {
                info.indexingDepths.Add(0);
                RegisterUse(info, expr);
            }
            return(expr);
        }
コード例 #13
0
        public static IVariableDeclaration GetVariable(IExpression exp)
        {
            IVariableDeclarationExpression exp_var_decl = exp as IVariableDeclarationExpression;

            if (exp_var_decl != null)
            {
                return(exp_var_decl.Variable);
            }

            IVariableReferenceExpression exp_var_ref = exp as IVariableReferenceExpression;

            if (exp_var_ref != null)
            {
                return(exp_var_ref.Variable.Resolve());
            }

            return(null);
        }
コード例 #14
0
        /// <summary>
        /// Converts references to variables which were declared inside loops, by adding indexing as appropriate.
        /// </summary>
        /// <param name="ivre"></param>
        /// <returns></returns>
        protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre)
        {
            IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(ivre);
            LoopVarInfo          lvi;

            if (!loopVarInfos.TryGetValue(ivd, out lvi))
            {
                return(ivre);
            }
            IExpression expr = Builder.VarRefExpr(lvi.arrayvd);

            for (int i = 0; i < lvi.indexVarRefs.Length; i++)
            {
                expr = Builder.ArrayIndex(expr, lvi.indexVarRefs[i]);
            }
            context.InputAttributes.CopyObjectAttributesTo(ivre, context.OutputAttributes, expr);
            return(expr);
        }
コード例 #15
0
        /// <summary>
        /// Converts a variable reference.
        /// </summary>
        /// <param name="ivre"></param>
        /// <returns></returns>
        protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre)
        {
            IVariableDeclaration         ivd  = ivre.Variable.Resolve();
            VariableToChannelInformation vtci = Context.InputAttributes.Get <VariableToChannelInformation>(ivd);

            // If deterministic variable do nothing.
            if (vtci == null || vtci.usageChannel == null)
            {
                return(ivre);
            }
            else if (Recognizer.IsBeingIndexed(context))
            {
                return(ivre);
            }
            else if (Recognizer.IsBeingMutated(context, ivre))
            {
                return(ivre);
            }
            else
            {
                return(vtci.usageChannel.ReplaceWithUsesChannel(ivre, Builder.LiteralExpr(vtci.shareAllUses ? 0 : vtci.useCount++)));
            }
        }
コード例 #16
0
ファイル: VariableTransform.cs プロジェクト: zouwuhe/infer
        /// <summary>
        /// Modify the argument of Infer to be the marginal channel variable i.e. Infer(a) transforms to Infer(a_marginal)
        /// </summary>
        /// <param name="imie"></param>
        ///
        /// <returns>The modified expression</returns>
        protected IExpression ConvertInfer(IMethodInvokeExpression imie)
        {
            IVariableReferenceExpression ivre = imie.Arguments[0] as IVariableReferenceExpression;

            if (ivre == null)
            {
                //Error("Argument to Infer() must be a variable reference, was " + imie.Arguments[0] + ".");
                return(imie);
            }
            // Find expression for the marginal of interest
            IVariableDeclaration ivd = ivre.Variable.Resolve();
            IVariableDeclaration marginalDecl;
            ExpressionEvaluator  eval  = new ExpressionEvaluator();
            QueryType            query = (imie.Arguments.Count < 3) ? null : (QueryType)eval.Evaluate(imie.Arguments[2]);
            bool isOutput = (query == QueryTypes.MarginalDividedByPrior);
            Dictionary <IVariableDeclaration, IVariableDeclaration> dict = isOutput ? useOfVariable : marginalOfVariable;

            if (!dict.TryGetValue(ivd, out marginalDecl))
            {
                return(imie); // The argument is constant
            }
            IMethodInvokeExpression mie = Builder.MethodInvkExpr();

            mie.Method = imie.Method;
            mie.Arguments.Add(Builder.VarRefExpr(marginalDecl));
            for (int i = 1; i < imie.Arguments.Count; i++)
            {
                mie.Arguments.Add(imie.Arguments[i]);
            }
            // move the IsInferred attribute to the marginal channel
            //context.OutputAttributes.Remove<IsInferred>(ivd);
            if (!context.OutputAttributes.Has <IsInferred>(marginalDecl))
            {
                context.OutputAttributes.Set(marginalDecl, new IsInferred());
            }
            return(mie);
        }
コード例 #17
0
        protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre)
        {
            if (Recognizer.IsBeingMutated(context, ivre))
            {
                return(ivre);
            }
            IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(ivre);

            if (ivd == null)
            {
                return(ivre);
            }
            if (!variablesAssigned.Contains(ivd))
            {
                Error(ivd + " is used before it is assigned to");
            }
            IVariableDeclaration useDecl;

            if (useOfVariable.TryGetValue(ivd, out useDecl))
            {
                return(Builder.VarRefExpr(useDecl));
            }
            return(ivre);
        }
コード例 #18
0
 // Shallow copy variable references for efficiency
 protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre)
 {
     return ConvertWithReplication(ivre);
 }
コード例 #19
0
 private void WriteVariableReferenceExpression(IVariableReferenceExpression expression, IFormatter formatter)
 {
     this.WriteVariableReference(expression.Variable, formatter);
 }
コード例 #20
0
        protected override IExpression ConvertMethodInvoke(IMethodInvokeExpression imie)
        {
            IExpression converted = base.ConvertMethodInvoke(imie);

            if (converted is IMethodInvokeExpression mie)
            {
                if (Recognizer.IsStaticGenericMethod(imie, new Func <PlaceHolder, ICompilerAttribute, PlaceHolder>(Attrib.Var)))
                {
                    IVariableReferenceExpression ivre   = imie.Arguments[0] as IVariableReferenceExpression;
                    IVariableDeclaration         target = ivre.Variable.Resolve();
                    IExpression expr = imie.Arguments[1];
                    AddAttribute(target, expr);
                    return(null);
                }
                else if (Recognizer.IsStaticMethod(imie, new Action <object, object>(Attrib.InitialiseTo)))
                {
                    IVariableReferenceExpression ivre   = imie.Arguments[0] as IVariableReferenceExpression;
                    IVariableDeclaration         target = ivre.Variable.Resolve();
                    context.OutputAttributes.Set(target, new InitialiseTo(imie.Arguments[1]));
                    return(null);
                }
                else if (CodeRecognizer.IsInfer(imie))
                {
                    // the arguments must not be substituted for their values, so we don't call ConvertExpression
                    IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(imie.Arguments[0]);
                    if (ivd != null)
                    {
                        var       vi    = VariableInformation.GetVariableInformation(context, ivd);
                        QueryType query = (imie.Arguments.Count < 3) ? null : (QueryType)evaluator.Evaluate(imie.Arguments[2]);
                        vi.NeedsMarginalDividedByPrior = (query == QueryTypes.MarginalDividedByPrior);
                    }
                    return(imie);
                }
                bool anyArgumentIsLiteral = mie.Arguments.Any(arg => arg is ILiteralExpression);
                if (anyArgumentIsLiteral)
                {
                    if (Recognizer.IsStaticMethod(converted, new Func <bool, bool, bool>(Factors.Factor.And)))
                    {
                        if (mie.Arguments.Any(arg => arg is ILiteralExpression ile && ile.Value.Equals(false)))
                        {
                            return(Builder.LiteralExpr(false));
                        }
                        // any remaining literals must be true, and therefore can be ignored.
                        var reducedArguments = mie.Arguments.Where(arg => !(arg is ILiteralExpression));
                        if (reducedArguments.Count() == 1)
                        {
                            return(reducedArguments.First());
                        }
                        else
                        {
                            return(Builder.LiteralExpr(true));
                        }
                    }
                    else if (Recognizer.IsStaticMethod(converted, new Func <bool, bool, bool>(Factors.Factor.Or)))
                    {
                        if (mie.Arguments.Any(arg => arg is ILiteralExpression ile && ile.Value.Equals(true)))
                        {
                            return(Builder.LiteralExpr(true));
                        }
                        // any remaining literals must be false, and therefore can be ignored.
                        var reducedArguments = mie.Arguments.Where(arg => !(arg is ILiteralExpression));
                        if (reducedArguments.Count() == 1)
                        {
                            return(reducedArguments.First());
                        }
                        else
                        {
                            return(Builder.LiteralExpr(false));
                        }
                    }
                    else if (Recognizer.IsStaticMethod(converted, new Func <bool, bool>(Factors.Factor.Not)))
                    {
                        bool allArgumentsAreLiteral = mie.Arguments.All(arg => arg is ILiteralExpression);
                        if (allArgumentsAreLiteral)
                        {
                            return(Builder.LiteralExpr(evaluator.Evaluate(mie)));
                        }
                    }
                }
            }
            return(converted);
        }
コード例 #21
0
 public virtual void VisitVariableReferenceExpression(IVariableReferenceExpression value)
 {
     this.VisitVariableReference(value.Variable);
 }
コード例 #22
0
 protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre)
 {
     liveVariables.Add(ivre.Variable.Variable);
     return(base.ConvertVariableRefExpr(ivre));
 }
コード例 #23
0
            //===========================================================
            //		Expression 分岐
            //===========================================================
            public virtual void WriteExpression(IExpression expression)
            {
                if (expression == null)
                {
                    return;
                }

                mwg.Reflector.CppCli.ExpressionWriter.WriteExpression(this, expression, false);

#if FALSE
#pragma warning disable 612

                IMemberInitializerExpression expression3 = expression as IMemberInitializerExpression;
                if (expression3 != null)
                {
                    this.WriteMemberInitializerExpression(expression3);
                    return;
                }

                IAddressOutExpression expression27 = expression as IAddressOutExpression;
                if (expression27 != null)
                {
                    this.WriteAddressOutExpression(expression27);
                    return;
                }

                IAddressReferenceExpression expression26 = expression as IAddressReferenceExpression;
                if (expression26 != null)
                {
                    this.WriteAddressReferenceExpression(expression26);
                    return;
                }

                IDelegateCreateExpression iDelegateCreateExpression = expression as IDelegateCreateExpression;
                if (iDelegateCreateExpression != null)
                {
                    this.WriteDelegateCreateExpression(iDelegateCreateExpression);
                    return;
                }

                IMethodInvokeExpression iMethodInvokeExpression = expression as IMethodInvokeExpression;
                if (iMethodInvokeExpression != null)
                {
                    this.WriteMethodInvokeExpression(iMethodInvokeExpression);
                    return;
                }

                IVariableDeclarationExpression expression15 = expression as IVariableDeclarationExpression;
                if (expression15 != null)
                {
                    this.WriteVariableDeclaration(expression15.Variable);
                    return;
                }

                ITypeOfExpression iTypeOfExpression = expression as ITypeOfExpression;
                if (iTypeOfExpression != null)
                {
                    this.WriteTypeOfExpression(iTypeOfExpression);
                    return;
                }

                ISnippetExpression iSnippetExpression = expression as ISnippetExpression;
                if (iSnippetExpression != null)
                {
                    this.WriteSnippetExpression(iSnippetExpression);
                    return;
                }

                IUnaryExpression iUnaryExpression = expression as IUnaryExpression;
                if (iUnaryExpression != null)
                {
                    this.WriteUnaryExpression(iUnaryExpression);
                    return;
                }

                IObjectCreateExpression iObjectCreateExpression = expression as IObjectCreateExpression;
                if (iObjectCreateExpression != null)
                {
                    this.WriteObjectCreateExpression(iObjectCreateExpression);
                    return;
                }

                IVariableReferenceExpression iVariableReferenceExpression = expression as IVariableReferenceExpression;
                if (iVariableReferenceExpression != null)
                {
                    this.WriteVariableReferenceExpression(iVariableReferenceExpression);
                    return;
                }

                IThisReferenceExpression expression12 = expression as IThisReferenceExpression;
                if (expression12 != null)
                {
                    this.WriteThisReferenceExpression(expression12);
                    return;
                }

                ITryCastExpression iTryCastExpression = expression as ITryCastExpression;
                if (iTryCastExpression != null)
                {
                    this.WriteTryCastExpression(iTryCastExpression);
                    return;
                }

                IConditionExpression expression9 = expression as IConditionExpression;
                if (expression9 != null)
                {
                    this.WriteConditionExpression(expression9);
                    return;
                }

                IFieldReferenceExpression iFieldReferenceExpression = expression as IFieldReferenceExpression;
                if (iFieldReferenceExpression != null)
                {
                    this.WriteFieldReferenceExpression(iFieldReferenceExpression);
                    return;
                }

                IPropertyIndexerExpression iPropertyIndexerExpression = expression as IPropertyIndexerExpression;
                if (iPropertyIndexerExpression != null)
                {
                    this.WritePropertyIndexerExpression(iPropertyIndexerExpression);
                    return;
                }

                ITypeReferenceExpression iTypeReferenceExpression = expression as ITypeReferenceExpression;
                if (iTypeReferenceExpression != null)
                {
                    this.WriteTypeReferenceExpression(iTypeReferenceExpression);
                    return;
                }

                IMethodReferenceExpression iMethodReferenceExpression = expression as IMethodReferenceExpression;
                if (iMethodReferenceExpression != null)
                {
                    this.WriteMethodReferenceExpression(iMethodReferenceExpression);
                    return;
                }

                IPropertyReferenceExpression iPropertyReferenceExpression = expression as IPropertyReferenceExpression;
                if (iPropertyReferenceExpression != null)
                {
                    this.WritePropertyReferenceExpression(iPropertyReferenceExpression);
                    return;
                }

                ICastExpression expression5 = expression as ICastExpression;
                if (expression5 != null)
                {
                    this.WriteCastExpression(expression5);
                    return;
                }

                ICanCastExpression iCanCastExpression = expression as ICanCastExpression;
                if (iCanCastExpression != null)
                {
                    this.WriteCanCastExpression(iCanCastExpression);
                    return;
                }

                ICastExpression iCastExpression = expression as ICastExpression;
                if (iCastExpression != null)
                {
                    this.WriteCastExpression(iCastExpression);
                    return;
                }

                ILiteralExpression literalExpression = expression as ILiteralExpression;
                if (literalExpression != null)
                {
                    this.WriteLiteralExpression(literalExpression);
                    return;
                }

                IBinaryExpression iBinaryExpression = expression as IBinaryExpression;
                if (iBinaryExpression != null)
                {
                    mwg.Reflector.CppCli.ExpressionWriter.WriteExpression(this, expression, true);
                    //this.WriteBinaryExpression(iBinaryExpression);
                    return;
                }

                IArrayIndexerExpression expression30 = expression as IArrayIndexerExpression;
                if (expression30 != null)
                {
                    this.WriteArrayIndexerExpression(expression30);
                    return;
                }

                IAddressDereferenceExpression expression29 = expression as IAddressDereferenceExpression;
                if (expression29 != null)
                {
                    this.WriteAddressDereferenceExpression(expression29);
                    return;
                }

                IAddressOfExpression expression28 = expression as IAddressOfExpression;
                if (expression28 != null)
                {
                    this.WriteAddressOfExpression(expression28);
                    return;
                }

                IArgumentListExpression expression25 = expression as IArgumentListExpression;
                if (expression25 != null)
                {
                    this.WriteArgumentListExpression(expression25);
                    return;
                }

                IBaseReferenceExpression iBaseReferenceExpression = expression as IBaseReferenceExpression;
                if (iBaseReferenceExpression != null)
                {
                    this.WriteBaseReferenceExpression(iBaseReferenceExpression);
                    return;
                }

                IArgumentReferenceExpression expression13 = expression as IArgumentReferenceExpression;
                if (expression13 != null)
                {
                    this.WriteArgumentReferenceExpression(expression13);
                    return;
                }

                IArrayCreateExpression expression10 = expression as IArrayCreateExpression;
                if (expression10 != null)
                {
                    this.WriteArrayCreateExpression(expression10);
                    return;
                }

                IAssignExpression iAssignExpression = expression as IAssignExpression;
                if (iAssignExpression != null)
                {
                    this.WriteAssignExpression(iAssignExpression);
                    return;
                }

                IBlockExpression expression2 = expression as IBlockExpression;
                if (expression2 != null)
                {
                    this.WriteBlockExpression(expression2);
                    return;
                }
#pragma warning restore 612

                this.Write(expression.ToString());
#endif
            }
コード例 #24
0
 public virtual void VisitVariableReferenceExpression(IVariableReferenceExpression value)
 {
     VisitVariableReference(value.Variable);
 }
コード例 #25
0
        protected override IExpression ConvertMethodInvoke(IMethodInvokeExpression imie)
        {
            IExpression result = base.ConvertMethodInvoke(imie);

            if (result is IMethodInvokeExpression)
            {
                imie = (IMethodInvokeExpression)result;
            }
            else
            {
                return(result);
            }
            if (UseJaggedSubarray && Recognizer.IsStaticGenericMethod(imie, new Func <IReadOnlyList <PlaceHolder>, IReadOnlyList <int>, IReadOnlyList <PlaceHolder> >(Collection.Subarray)))
            {
                // check for the form Subarray(arrayExpr, indices[i]) where arrayExpr does not depend on i
                IExpression arrayExpr = imie.Arguments[0];
                IExpression arg1      = imie.Arguments[1];
                if (arg1 is IArrayIndexerExpression)
                {
                    IArrayIndexerExpression index = (IArrayIndexerExpression)arg1;
                    if (index.Indices.Count == 1 && index.Indices[0] is IVariableReferenceExpression)
                    {
                        // index has the form indices[i]
                        List <IStatement> targetLoops = Containers.GetLoopsNeededForExpression(context, arrayExpr, -1, false);
                        List <IStatement> indexLoops  = Containers.GetLoopsNeededForExpression(context, index.Target, -1, false);
                        Set <IStatement>  parentLoops = new Set <IStatement>();
                        parentLoops.AddRange(targetLoops);
                        parentLoops.AddRange(indexLoops);
                        IVariableReferenceExpression innerIndex = (IVariableReferenceExpression)index.Indices[0];
                        IForStatement innerLoop = Recognizer.GetLoopForVariable(context, innerIndex);
                        foreach (IStatement loop in parentLoops)
                        {
                            if (Containers.ContainersAreEqual(loop, innerLoop))
                            {
                                // arrayExpr depends on i
                                return(imie);
                            }
                        }
                        IVariableDeclaration arrayVar = Recognizer.GetVariableDeclaration(arrayExpr);
                        // If the variable is not stochastic, return
                        if (arrayVar == null)
                        {
                            return(imie);
                        }
                        VariableInformation arrayInfo = VariableInformation.GetVariableInformation(context, arrayVar);
                        if (!arrayInfo.IsStochastic)
                        {
                            return(imie);
                        }
                        object indexVar = Recognizer.GetDeclaration(index);
                        VariableInformation indexInfo = VariableInformation.GetVariableInformation(context, indexVar);
                        int         depth             = Recognizer.GetIndexingDepth(index);
                        IExpression resultSize        = indexInfo.sizes[depth][0];
                        var         indices           = Recognizer.GetIndices(index);
                        int         replaceCount      = 0;
                        resultSize = indexInfo.ReplaceIndexVars(context, resultSize, indices, null, ref replaceCount);
                        indexInfo.DefineIndexVarsUpToDepth(context, depth + 1);
                        IVariableDeclaration resultIndex = indexInfo.indexVars[depth][0];
                        Type arrayType   = arrayExpr.GetExpressionType();
                        Type elementType = Util.GetElementType(arrayType);

                        // create a new variable arrayExpr_indices = JaggedSubarray(arrayExpr, indices)
                        string name = ToString(arrayExpr) + "_" + ToString(index.Target);

                        var stmts        = Builder.StmtCollection();
                        var arrayIndices = Recognizer.GetIndices(arrayExpr);
                        var bracket      = Builder.ExprCollection();
                        bracket.Add(Builder.ArrayIndex(index, Builder.VarRefExpr(resultIndex)));
                        arrayIndices.Add(bracket);
                        IExpression          loopSize = Recognizer.LoopSizeExpression(innerLoop);
                        IVariableDeclaration temp     = arrayInfo.DeriveArrayVariable(stmts, context, name, resultSize, resultIndex, arrayIndices);
                        VariableInformation  tempInfo = VariableInformation.GetVariableInformation(context, temp);
                        stmts.Clear();
                        IVariableDeclaration newvd = tempInfo.DeriveArrayVariable(stmts, context, name, loopSize, Recognizer.GetVariableDeclaration(innerIndex));
                        if (!context.InputAttributes.Has <DerivedVariable>(newvd))
                        {
                            context.InputAttributes.Set(newvd, new DerivedVariable());
                        }
                        IExpression rhs = Builder.StaticGenericMethod(new Func <IReadOnlyList <PlaceHolder>, int[][], PlaceHolder[][]>(Collection.JaggedSubarray),
                                                                      new Type[] { elementType }, arrayExpr, index.Target);
                        context.InputAttributes.CopyObjectAttributesTo <Algorithm>(newvd, context.OutputAttributes, rhs);
                        stmts.Add(Builder.AssignStmt(Builder.VarRefExpr(newvd), rhs));

                        // Reduce memory consumption by declaring the clone outside of unnecessary loops.
                        // This way, the item is cloned outside the loop and then replicated, instead of replicating the entire array and cloning the item.
                        Containers containers = new Containers(context);
                        containers = RemoveReferencesTo(containers, innerIndex);
                        containers = Containers.RemoveUnusedLoops(containers, context, rhs);
                        if (context.InputAttributes.Has <DoNotSendEvidence>(arrayVar))
                        {
                            containers = Containers.RemoveStochasticConditionals(containers, context);
                        }
                        // To put the declaration in the desired containers, we find an ancestor which includes as many of the containers as possible,
                        // then wrap the declaration with the remaining containers.
                        int        ancIndex = containers.GetMatchingAncestorIndex(context);
                        Containers missing  = containers.GetContainersNotInContext(context, ancIndex);
                        stmts = Containers.WrapWithContainers(stmts, missing.outputs);
                        context.AddStatementsBeforeAncestorIndex(ancIndex, stmts);
                        context.InputAttributes.Set(newvd, containers);

                        // convert into arrayExpr_indices[i]
                        IExpression newExpr = Builder.ArrayIndex(Builder.VarRefExpr(newvd), innerIndex);
                        newExpr = Builder.StaticGenericMethod(new Func <PlaceHolder, PlaceHolder>(Clone.Copy <PlaceHolder>), new Type[] { newExpr.GetExpressionType() }, newExpr);
                        return(newExpr);
                    }
                }
            }
            return(imie);
        }
コード例 #26
0
        /// <summary>
        /// This method does all the work of converting literal indexing expressions.
        /// </summary>
        /// <param name="iaie"></param>
        /// <returns></returns>
        protected override IExpression ConvertArrayIndexer(IArrayIndexerExpression iaie)
        {
            IndexAnalysisTransform.IndexInfo info;
            if (!analysis.indexInfoOf.TryGetValue(iaie, out info))
            {
                return(base.ConvertArrayIndexer(iaie));
            }
            // Determine if this is a definition i.e. the variable is on the left hand side of an assignment
            // This must be done before base.ConvertArrayIndexer changes the expression!
            bool isDef = Recognizer.IsBeingMutated(context, iaie);

            if (info.clone != null)
            {
                if (isDef)
                {
                    // check that extra literal indices in the target are zero.
                    // for example, if iae is x[i][0] = (...) then it is safe to add x_uses[i] = Rep(x[i])
                    // if iae is x[i][1] = (...) then it is safe to add x_uses[i][1] = Rep(x[i][1])
                    // but not x_uses[i] = Rep(x[i]) since this will be a duplicate.
                    bool   extraLiteralsAreZero = true;
                    int    parentIndex          = context.InputStack.Count - 2;
                    object parent = context.GetAncestor(parentIndex);
                    while (parent is IArrayIndexerExpression)
                    {
                        IArrayIndexerExpression parent_iaie = (IArrayIndexerExpression)parent;
                        foreach (IExpression index in parent_iaie.Indices)
                        {
                            if (index is ILiteralExpression)
                            {
                                int value = (int)((ILiteralExpression)index).Value;
                                if (value != 0)
                                {
                                    extraLiteralsAreZero = false;
                                    break;
                                }
                            }
                        }
                        parentIndex--;
                        parent = context.GetAncestor(parentIndex);
                    }
                    if (false && extraLiteralsAreZero)
                    {
                        // change:
                        //   array[0] = f()
                        // into:
                        //   array_item0 = f()
                        //   array[0] = Copy(array_item0)
                        IExpression copy = Builder.StaticGenericMethod(new Func <PlaceHolder, PlaceHolder>(Clone.Copy <PlaceHolder>), new Type[] { iaie.GetExpressionType() },
                                                                       info.clone);
                        IStatement copySt = Builder.AssignStmt(iaie, copy);
                        context.AddStatementAfterCurrent(copySt);
                    }
                }
                return(info.clone);
            }

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

            IVariableDeclaration originalBaseVar = Recognizer.GetVariableDeclaration(iaie);

            // If the variable is not stochastic, return
            if (!CodeRecognizer.IsStochastic(context, originalBaseVar))
            {
                return(iaie);
            }

            IExpression          newExpr    = null;
            IVariableDeclaration baseVar    = originalBaseVar;
            IVariableDeclaration newvd      = null;
            IExpression          rhsExpr    = null;
            Containers           containers = info.containers;
            Type tp = iaie.GetExpressionType();

            if (tp == null)
            {
                Error("Could not determine type of expression: " + iaie);
                return(iaie);
            }
            var stmts      = Builder.StmtCollection();
            var stmtsAfter = Builder.StmtCollection();

            // does the expression have the form array[indices[k]][indices2[k]][indices3[k]]?
            if (newvd == null && UseGetItems && iaie.Target is IArrayIndexerExpression &&
                iaie.Indices.Count == 1 && iaie.Indices[0] is IArrayIndexerExpression)
            {
                IArrayIndexerExpression index3 = (IArrayIndexerExpression)iaie.Indices[0];
                IArrayIndexerExpression iaie2  = (IArrayIndexerExpression)iaie.Target;
                if (index3.Indices.Count == 1 && index3.Indices[0] is IVariableReferenceExpression &&
                    iaie2.Target is IArrayIndexerExpression &&
                    iaie2.Indices.Count == 1 && iaie2.Indices[0] is IArrayIndexerExpression)
                {
                    IArrayIndexerExpression index2 = (IArrayIndexerExpression)iaie2.Indices[0];
                    IArrayIndexerExpression iaie3  = (IArrayIndexerExpression)iaie2.Target;
                    if (index2.Indices.Count == 1 && index2.Indices[0] is IVariableReferenceExpression &&
                        iaie3.Indices.Count == 1 && iaie3.Indices[0] is IArrayIndexerExpression)
                    {
                        IArrayIndexerExpression      index      = (IArrayIndexerExpression)iaie3.Indices[0];
                        IVariableReferenceExpression innerIndex = (IVariableReferenceExpression)index.Indices[0];
                        IForStatement innerLoop = Recognizer.GetLoopForVariable(context, innerIndex);
                        if (index.Indices.Count == 1 && index2.Indices[0].Equals(innerIndex) &&
                            index3.Indices[0].Equals(innerIndex) &&
                            innerLoop != null && AreLoopsDisjoint(innerLoop, iaie3.Target, index.Target))
                        {
                            // expression has the form array[indices[k]][indices2[k]][indices3[k]]
                            if (isDef)
                            {
                                Error("fancy indexing not allowed on left hand side");
                                return(iaie);
                            }
                            WarnIfLocal(index.Target, iaie3.Target, iaie);
                            WarnIfLocal(index2.Target, iaie3.Target, iaie);
                            WarnIfLocal(index3.Target, iaie3.Target, iaie);
                            containers = RemoveReferencesTo(containers, innerIndex);
                            IExpression loopSize = Recognizer.LoopSizeExpression(innerLoop);
                            var         indices  = Recognizer.GetIndices(iaie);
                            // Build name of replacement variable from index values
                            StringBuilder sb = new StringBuilder("_item");
                            AppendIndexString(sb, iaie3);
                            AppendIndexString(sb, iaie2);
                            AppendIndexString(sb, iaie);
                            string name = ToString(iaie3.Target) + sb.ToString();
                            VariableInformation varInfo = VariableInformation.GetVariableInformation(context, baseVar);
                            newvd = varInfo.DeriveArrayVariable(stmts, context, name, loopSize, Recognizer.GetVariableDeclaration(innerIndex), indices);
                            if (!context.InputAttributes.Has <DerivedVariable>(newvd))
                            {
                                context.InputAttributes.Set(newvd, new DerivedVariable());
                            }
                            IExpression getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <IReadOnlyList <IReadOnlyList <PlaceHolder> > >, IReadOnlyList <int>, IReadOnlyList <int>, IReadOnlyList <int>, PlaceHolder[]>(Collection.GetItemsFromDeepJagged),
                                                                               new Type[] { tp }, iaie3.Target, index.Target, index2.Target, index3.Target);
                            context.InputAttributes.CopyObjectAttributesTo <Algorithm>(baseVar, context.OutputAttributes, getItems);
                            stmts.Add(Builder.AssignStmt(Builder.VarRefExpr(newvd), getItems));
                            newExpr = Builder.ArrayIndex(Builder.VarRefExpr(newvd), innerIndex);
                            rhsExpr = getItems;
                        }
                    }
                }
            }
            // does the expression have the form array[indices[k]][indices2[k]]?
            if (newvd == null && UseGetItems && iaie.Target is IArrayIndexerExpression &&
                iaie.Indices.Count == 1 && iaie.Indices[0] is IArrayIndexerExpression)
            {
                IArrayIndexerExpression index2 = (IArrayIndexerExpression)iaie.Indices[0];
                IArrayIndexerExpression target = (IArrayIndexerExpression)iaie.Target;
                if (index2.Indices.Count == 1 && index2.Indices[0] is IVariableReferenceExpression &&
                    target.Indices.Count == 1 && target.Indices[0] is IArrayIndexerExpression)
                {
                    IVariableReferenceExpression innerIndex = (IVariableReferenceExpression)index2.Indices[0];
                    IArrayIndexerExpression      index      = (IArrayIndexerExpression)target.Indices[0];
                    IForStatement innerLoop = Recognizer.GetLoopForVariable(context, innerIndex);
                    if (index.Indices.Count == 1 && index.Indices[0].Equals(innerIndex) &&
                        innerLoop != null && AreLoopsDisjoint(innerLoop, target.Target, index.Target))
                    {
                        // expression has the form array[indices[k]][indices2[k]]
                        if (isDef)
                        {
                            Error("fancy indexing not allowed on left hand side");
                            return(iaie);
                        }
                        var innerLoops = new List <IForStatement>();
                        innerLoops.Add(innerLoop);
                        var indexTarget  = index.Target;
                        var index2Target = index2.Target;
                        // check if the index array is jagged, i.e. array[indices[k][j]]
                        while (indexTarget is IArrayIndexerExpression && index2Target is IArrayIndexerExpression)
                        {
                            IArrayIndexerExpression indexTargetExpr  = (IArrayIndexerExpression)indexTarget;
                            IArrayIndexerExpression index2TargetExpr = (IArrayIndexerExpression)index2Target;
                            if (indexTargetExpr.Indices.Count == 1 && indexTargetExpr.Indices[0] is IVariableReferenceExpression &&
                                index2TargetExpr.Indices.Count == 1 && index2TargetExpr.Indices[0] is IVariableReferenceExpression)
                            {
                                IVariableReferenceExpression innerIndexTarget  = (IVariableReferenceExpression)indexTargetExpr.Indices[0];
                                IVariableReferenceExpression innerIndex2Target = (IVariableReferenceExpression)index2TargetExpr.Indices[0];
                                IForStatement indexTargetLoop = Recognizer.GetLoopForVariable(context, innerIndexTarget);
                                if (indexTargetLoop != null && AreLoopsDisjoint(indexTargetLoop, target.Target, indexTargetExpr.Target) &&
                                    innerIndexTarget.Equals(innerIndex2Target))
                                {
                                    innerLoops.Add(indexTargetLoop);
                                    indexTarget  = indexTargetExpr.Target;
                                    index2Target = index2TargetExpr.Target;
                                }
                                else
                                {
                                    break;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                        WarnIfLocal(indexTarget, target.Target, iaie);
                        WarnIfLocal(index2Target, target.Target, iaie);
                        innerLoops.Reverse();
                        var loopSizes    = innerLoops.ListSelect(ifs => new[] { Recognizer.LoopSizeExpression(ifs) });
                        var newIndexVars = innerLoops.ListSelect(ifs => new[] { Recognizer.LoopVariable(ifs) });
                        // Build name of replacement variable from index values
                        StringBuilder sb = new StringBuilder("_item");
                        AppendIndexString(sb, target);
                        AppendIndexString(sb, iaie);
                        string name = ToString(target.Target) + sb.ToString();
                        VariableInformation varInfo = VariableInformation.GetVariableInformation(context, baseVar);
                        var indices = Recognizer.GetIndices(iaie);
                        newvd = varInfo.DeriveArrayVariable(stmts, context, name, loopSizes, newIndexVars, indices);
                        if (!context.InputAttributes.Has <DerivedVariable>(newvd))
                        {
                            context.InputAttributes.Set(newvd, new DerivedVariable());
                        }
                        IExpression getItems;
                        if (innerLoops.Count == 1)
                        {
                            getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <IReadOnlyList <PlaceHolder> >, IReadOnlyList <int>, IReadOnlyList <int>, PlaceHolder[]>(Collection.GetItemsFromJagged),
                                                                   new Type[] { tp }, target.Target, indexTarget, index2Target);
                        }
                        else if (innerLoops.Count == 2)
                        {
                            getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <IReadOnlyList <PlaceHolder> >, IReadOnlyList <IReadOnlyList <int> >, IReadOnlyList <IReadOnlyList <int> >, PlaceHolder[][]>(Collection.GetJaggedItemsFromJagged),
                                                                   new Type[] { tp }, target.Target, indexTarget, index2Target);
                        }
                        else
                        {
                            throw new NotImplementedException($"innerLoops.Count = {innerLoops.Count}");
                        }
                        context.InputAttributes.CopyObjectAttributesTo <Algorithm>(baseVar, context.OutputAttributes, getItems);
                        stmts.Add(Builder.AssignStmt(Builder.VarRefExpr(newvd), getItems));
                        var newIndices = newIndexVars.ListSelect(ivds => Util.ArrayInit(ivds.Length, i => Builder.VarRefExpr(ivds[i])));
                        newExpr = Builder.JaggedArrayIndex(Builder.VarRefExpr(newvd), newIndices);
                        rhsExpr = getItems;
                    }
                    else if (HasAnyCommonLoops(index, index2))
                    {
                        Warning($"This model will consume excess memory due to the indexing expression {iaie} since {index} and {index2} have larger depth than the compiler can handle.");
                    }
                }
            }
            if (newvd == null)
            {
                IArrayIndexerExpression originalExpr = iaie;
                if (UseGetItems)
                {
                    iaie = (IArrayIndexerExpression)base.ConvertArrayIndexer(iaie);
                }
                if (!object.ReferenceEquals(iaie.Target, originalExpr.Target) && false)
                {
                    // TODO: determine if this warning is useful or not
                    string warningText = "This model may consume excess memory due to the jagged indexing expression {0}";
                    Warning(string.Format(warningText, originalExpr));
                }

                // get the baseVar of the new expression.
                baseVar = Recognizer.GetVariableDeclaration(iaie);
                VariableInformation varInfo = VariableInformation.GetVariableInformation(context, baseVar);

                var indices = Recognizer.GetIndices(iaie);
                // Build name of replacement variable from index values
                StringBuilder sb = new StringBuilder("_item");
                AppendIndexString(sb, iaie);
                string name = ToString(iaie.Target) + sb.ToString();

                // does the expression have the form array[indices[k]]?
                if (UseGetItems && iaie.Indices.Count == 1 && iaie.Indices[0] is IArrayIndexerExpression)
                {
                    IArrayIndexerExpression index = (IArrayIndexerExpression)iaie.Indices[0];
                    if (index.Indices.Count == 1 && index.Indices[0] is IVariableReferenceExpression)
                    {
                        // expression has the form array[indices[k]]
                        IVariableReferenceExpression innerIndex = (IVariableReferenceExpression)index.Indices[0];
                        IForStatement innerLoop = Recognizer.GetLoopForVariable(context, innerIndex);
                        if (innerLoop != null && AreLoopsDisjoint(innerLoop, iaie.Target, index.Target))
                        {
                            if (isDef)
                            {
                                Error("fancy indexing not allowed on left hand side");
                                return(iaie);
                            }
                            var innerLoops = new List <IForStatement>();
                            innerLoops.Add(innerLoop);
                            var indexTarget = index.Target;
                            // check if the index array is jagged, i.e. array[indices[k][j]]
                            while (indexTarget is IArrayIndexerExpression)
                            {
                                IArrayIndexerExpression index2 = (IArrayIndexerExpression)indexTarget;
                                if (index2.Indices.Count == 1 && index2.Indices[0] is IVariableReferenceExpression)
                                {
                                    IVariableReferenceExpression innerIndex2 = (IVariableReferenceExpression)index2.Indices[0];
                                    IForStatement innerLoop2 = Recognizer.GetLoopForVariable(context, innerIndex2);
                                    if (innerLoop2 != null && AreLoopsDisjoint(innerLoop2, iaie.Target, index2.Target))
                                    {
                                        innerLoops.Add(innerLoop2);
                                        indexTarget = index2.Target;
                                        // This limit must match the number of handled cases below.
                                        if (innerLoops.Count == 3)
                                        {
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
                            WarnIfLocal(indexTarget, iaie.Target, originalExpr);
                            innerLoops.Reverse();
                            var loopSizes    = innerLoops.ListSelect(ifs => new[] { Recognizer.LoopSizeExpression(ifs) });
                            var newIndexVars = innerLoops.ListSelect(ifs => new[] { Recognizer.LoopVariable(ifs) });
                            newvd = varInfo.DeriveArrayVariable(stmts, context, name, loopSizes, newIndexVars, indices);
                            if (!context.InputAttributes.Has <DerivedVariable>(newvd))
                            {
                                context.InputAttributes.Set(newvd, new DerivedVariable());
                            }
                            IExpression getItems;
                            if (innerLoops.Count == 1)
                            {
                                getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <PlaceHolder>, IReadOnlyList <int>, PlaceHolder[]>(Collection.GetItems),
                                                                       new Type[] { tp }, iaie.Target, indexTarget);
                            }
                            else if (innerLoops.Count == 2)
                            {
                                getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <PlaceHolder>, IReadOnlyList <IReadOnlyList <int> >, PlaceHolder[][]>(Collection.GetJaggedItems),
                                                                       new Type[] { tp }, iaie.Target, indexTarget);
                            }
                            else if (innerLoops.Count == 3)
                            {
                                getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <PlaceHolder>, IReadOnlyList <IReadOnlyList <IReadOnlyList <int> > >, PlaceHolder[][][]>(Collection.GetDeepJaggedItems),
                                                                       new Type[] { tp }, iaie.Target, indexTarget);
                            }
                            else
                            {
                                throw new NotImplementedException($"innerLoops.Count = {innerLoops.Count}");
                            }
                            context.InputAttributes.CopyObjectAttributesTo <Algorithm>(baseVar, context.OutputAttributes, getItems);
                            stmts.Add(Builder.AssignStmt(Builder.VarRefExpr(newvd), getItems));
                            var newIndices = newIndexVars.ListSelect(ivds => Util.ArrayInit(ivds.Length, i => Builder.VarRefExpr(ivds[i])));
                            newExpr = Builder.JaggedArrayIndex(Builder.VarRefExpr(newvd), newIndices);
                            rhsExpr = getItems;
                        }
                    }
                }
                if (newvd == null)
                {
                    if (UseGetItems && info.count < 2)
                    {
                        return(iaie);
                    }
                    try
                    {
                        newvd = varInfo.DeriveIndexedVariable(stmts, context, name, indices, copyInitializer: isDef);
                    }
                    catch (Exception ex)
                    {
                        Error(ex.Message, ex);
                        return(iaie);
                    }
                    context.OutputAttributes.Remove <DerivedVariable>(newvd);
                    newExpr = Builder.VarRefExpr(newvd);
                    rhsExpr = iaie;
                    if (isDef)
                    {
                        // change:
                        //   array[0] = f()
                        // into:
                        //   array_item0 = f()
                        //   array[0] = Copy(array_item0)
                        IExpression copy   = Builder.StaticGenericMethod(new Func <PlaceHolder, PlaceHolder>(Clone.Copy), new Type[] { tp }, newExpr);
                        IStatement  copySt = Builder.AssignStmt(iaie, copy);
                        stmtsAfter.Add(copySt);
                        if (!context.InputAttributes.Has <DerivedVariable>(baseVar))
                        {
                            context.InputAttributes.Set(baseVar, new DerivedVariable());
                        }
                    }
                    else if (!info.IsAssignedTo)
                    {
                        // change:
                        //   x = f(array[0])
                        // into:
                        //   array_item0 = Copy(array[0])
                        //   x = f(array_item0)
                        IExpression copy   = Builder.StaticGenericMethod(new Func <PlaceHolder, PlaceHolder>(Clone.Copy), new Type[] { tp }, iaie);
                        IStatement  copySt = Builder.AssignStmt(Builder.VarRefExpr(newvd), copy);
                        //if (attr != null) context.OutputAttributes.Set(copySt, attr);
                        stmts.Add(copySt);
                        context.InputAttributes.Set(newvd, new DerivedVariable());
                    }
                }
            }

            // Reduce memory consumption by declaring the clone outside of unnecessary loops.
            // This way, the item is cloned outside the loop and then replicated, instead of replicating the entire array and cloning the item.
            containers = Containers.RemoveUnusedLoops(containers, context, rhsExpr);
            if (context.InputAttributes.Has <DoNotSendEvidence>(originalBaseVar))
            {
                containers = Containers.RemoveStochasticConditionals(containers, context);
            }
            if (true)
            {
                IStatement st = GetBindingSetContainer(FilterBindingSet(info.bindings,
                                                                        binding => Containers.ContainsExpression(containers.inputs, context, binding.GetExpression())));
                if (st != null)
                {
                    containers.Add(st);
                }
            }
            // To put the declaration in the desired containers, we find an ancestor which includes as many of the containers as possible,
            // then wrap the declaration with the remaining containers.
            int        ancIndex = containers.GetMatchingAncestorIndex(context);
            Containers missing  = containers.GetContainersNotInContext(context, ancIndex);

            stmts = Containers.WrapWithContainers(stmts, missing.outputs);
            context.AddStatementsBeforeAncestorIndex(ancIndex, stmts);
            stmtsAfter = Containers.WrapWithContainers(stmtsAfter, missing.outputs);
            context.AddStatementsAfterAncestorIndex(ancIndex, stmtsAfter);
            context.InputAttributes.Set(newvd, containers);
            info.clone = newExpr;
            return(newExpr);
        }
コード例 #27
0
 protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre)
 {
     ProcessExpression(ivre);
     return(ivre);
 }
コード例 #28
0
 public virtual void VisitVariableReferenceExpression(IVariableReferenceExpression e)
 {
 }
コード例 #29
0
        private static void WriteAssign(LanguageWriter w, IAssignExpression exp)
        {
#if EXTRA_TEMP
            // 無駄な変数の除去
            //   之はその内に StatementAnalyze に引っ越した方が分かりやすいかも知れない
            //   但し、その場合には式内で代入を行う場合には対応出来ない (例: (i=j)==0 等)
            IVariableDeclarationExpression target  = exp.Target as IVariableDeclarationExpression;
            IVariableReferenceExpression   target2 = exp.Target as IVariableReferenceExpression;
            IVariableReferenceExpression   right   = exp.Expression as IVariableReferenceExpression;
            if (w.ExtraTemporaries != null)
            {
                // 無駄変数の宣言
                if (target != null)
                {
                    for (int i = 0; i < w.ExtraTemporaries.Length; i++)
                    {
                        if (!w.EssentialTemporaries[i] && target.Variable.Name == w.ExtraTemporaries[i])
                        {
                            return;
                        }
                    }
                }

                // 無駄変数から無駄変数への受け渡し
                if (target2 != null && right != null)
                {
                    int iTarget = -1;
                    int iRight  = -1;
                    for (int j = 0; j < w.ExtraTemporaries.Length; j++)
                    {
                        if (target2.Variable.ToString() == w.ExtraTemporaries[j])
                        {
                            iTarget = j;
                            w.VerifyCorrectBlock(j);
                        }
                        if (right.Variable.ToString() == w.ExtraTemporaries[j])
                        {
                            iRight = j;
                            w.VerifyCorrectBlock(j);
                        }
                    }
                    if (iTarget >= 0 && !w.EssentialTemporaries[iTarget])
                    {
                        string str;
                        if (iRight >= 0 && !w.EssentialTemporaries[iRight])
                        {
                            if (w.ExtraMappings[iRight] == null)
                            {
                                w.EssentialTemporaries[iRight] = true;
                                str = null;
                            }
                            else
                            {
                                str = w.ExtraMappings[iRight];
                            }
                        }
                        else
                        {
                            str = right.Variable.ToString();
                        }
                        if (str != null && target2.Variable.ToString()[0] == str[0])
                        {
                            w.ExtraMappings[iTarget] = str;
                            return;
                        }
                    }
                }
            }
#endif
            WriteExpression(w, exp.Target, false);
            w.Write(" = ");
            WriteExpression(w, exp.Expression, false);
        }
コード例 #30
0
        //===========================================================
        //		using の変換
        //===========================================================
        /// <summary>
        /// Using 文を他の構文に変換して、yields に変換後の Statement を書き込みます。
        /// </summary>
        /// <param name="yields">変換後の Statement の書き込み先を指定します。</param>
        /// <param name="state">using 構文を表現する Statement を指定します。</param>
        /// <param name="last">state が Statements の中で最後の Statement か否かを指定します。</param>
        public static void TransformUsingStatement(Gen::List <IStatement> yields, IUsingStatement state, bool last)
        {
            // 変数の宣言の場合
            IAssignExpression assig = state.Expression as IAssignExpression;

            if (assig != null)
            {
                do
                {
                    IVariableDeclarationExpression var_decl_x = assig.Target as IVariableDeclarationExpression;
                    if (var_decl_x == null)
                    {
                        continue;
                    }

                    IVariableDeclaration var_decl = var_decl_x.Variable as IVariableDeclaration;
                    if (var_decl == null)
                    {
                        continue;
                    }

                    IObjectCreateExpression exp_create = assig.Expression as IObjectCreateExpression;
                    if (exp_create != null)
                    {
                        LocalRefVariableStatement s_lr = new LocalRefVariableStatement(var_decl, assig.Expression, state.Body);
                        s_lr.noblock = last;
                        yields.Add(s_lr);
                    }
                    else
                    {
                        //yields.Add(new ExpressionStatement(assig));
                        //yields.Add(state.Body);
                        //yields.Add(new DeleteStatement(new VariableReferenceExpression(var_decl)));
                        //↑ 中で例外が起こったときのことを考えていない。

                        // 宣言部分と代入部分を分離
                        IStatement s_decl = new ExpressionStatement(var_decl_x);
                        IStatement s_asgn = new ExpressionStatement(
                            new AssignExpression(
                                new VariableReferenceExpression(var_decl),
                                assig.Expression
                                )
                            );
                        IStatement s_delete = new DeleteStatement(new VariableReferenceExpression(var_decl));

                        // 宣言
                        yields.Add(s_decl);

                        // try-finally
                        BlockStatement try_block = new BlockStatement();
                        try_block.Statements.Add(s_asgn);
                        try_block.Statements.AddRange(state.Body.Statements);
                        BlockStatement finally_block = new BlockStatement();
                        finally_block.Statements.Add(s_delete);
                        TryCatchFinallyStatement s_tcf = new TryCatchFinallyStatement(try_block);
                        s_tcf.Finally = finally_block;
                        yields.Add(s_tcf);
                    }
                    return;
                }while(false);

                throw new InterfaceNotImplementedException("×実装中×", typeof(IVariableDeclarationExpression), assig.Target);
            }

            // 変数の参照の場合
            IVariableReferenceExpression varref = state.Expression as IVariableReferenceExpression;

            if (varref != null)
            {
                IStatement s_delete = new DeleteStatement(varref);

                // try-finally
                TryCatchFinallyStatement s_tcf         = new TryCatchFinallyStatement(state.Body);
                BlockStatement           finally_block = new BlockStatement();
                finally_block.Statements.Add(s_delete);
                s_tcf.Finally = finally_block;
                yields.Add(s_tcf);
                return;
            }

            throw new InterfaceNotImplementedException(
                      "Unexpected using-statement expression interface (expects IAssignExpression or IVariableReferenceExpression)",
                      typeof(IAssignExpression), state.Expression);
        }
コード例 #31
0
        protected override IExpression ConvertMethodInvoke(IMethodInvokeExpression imie)
        {
            if (Recognizer.IsStaticGenericMethod(imie, new Func <PlaceHolder, ICompilerAttribute, PlaceHolder>(Attrib.Var)))
            {
                IVariableReferenceExpression ivre   = imie.Arguments[0] as IVariableReferenceExpression;
                IVariableDeclaration         target = ivre.Variable.Resolve();
                IExpression expr = CodeRecognizer.RemoveCast(imie.Arguments[1]);
                AddAttribute(target, expr);
                return(null);
            }
            else if (Recognizer.IsStaticMethod(imie, new Action <object, object>(Attrib.InitialiseTo)))
            {
                IVariableReferenceExpression ivre   = CodeRecognizer.RemoveCast(imie.Arguments[0]) as IVariableReferenceExpression;
                IVariableDeclaration         target = ivre.Variable.Resolve();
                context.OutputAttributes.Set(target, new InitialiseTo(imie.Arguments[1]));
                return(null);
            }
            else if (CodeRecognizer.IsInfer(imie))
            {
                inferCount++;
                object decl = Recognizer.GetDeclaration(imie.Arguments[0]);
                if (decl != null && !context.InputAttributes.Has <IsInferred>(decl))
                {
                    context.InputAttributes.Set(decl, new IsInferred());
                }
                // the arguments must not be substituted for their values, so we don't call ConvertExpression
                List <IExpression> newArgs = new List <IExpression>();
                foreach (var arg in imie.Arguments)
                {
                    newArgs.Add(CodeRecognizer.RemoveCast(arg));
                }
                IMethodInvokeExpression mie = Builder.MethodInvkExpr();
                mie.Method = imie.Method;
                mie.Arguments.AddRange(newArgs);
                context.InputAttributes.CopyObjectAttributesTo(imie, context.OutputAttributes, mie);
                return(mie);
            }
            IExpression converted = base.ConvertMethodInvoke(imie);

            if (converted is IMethodInvokeExpression)
            {
                var  mie   = (IMethodInvokeExpression)converted;
                bool isAnd = Recognizer.IsStaticMethod(converted, new Func <bool, bool, bool>(Factors.Factor.And));
                bool isOr  = Recognizer.IsStaticMethod(converted, new Func <bool, bool, bool>(Factors.Factor.Or));
                bool anyArgumentIsLiteral = mie.Arguments.Any(arg => arg is ILiteralExpression);
                if (anyArgumentIsLiteral)
                {
                    if (isAnd)
                    {
                        if (mie.Arguments.Any(arg => arg is ILiteralExpression && ((ILiteralExpression)arg).Value.Equals(false)))
                        {
                            return(Builder.LiteralExpr(false));
                        }
                        // any remaining literals must be true, and therefore can be ignored.
                        var reducedArguments = mie.Arguments.Where(arg => !(arg is ILiteralExpression));
                        if (reducedArguments.Count() == 1)
                        {
                            return(reducedArguments.First());
                        }
                        else
                        {
                            return(Builder.LiteralExpr(true));
                        }
                    }
                    else if (isOr)
                    {
                        if (mie.Arguments.Any(arg => arg is ILiteralExpression && ((ILiteralExpression)arg).Value.Equals(true)))
                        {
                            return(Builder.LiteralExpr(true));
                        }
                        // any remaining literals must be false, and therefore can be ignored.
                        var reducedArguments = mie.Arguments.Where(arg => !(arg is ILiteralExpression));
                        if (reducedArguments.Count() == 1)
                        {
                            return(reducedArguments.First());
                        }
                        else
                        {
                            return(Builder.LiteralExpr(false));
                        }
                    }
                    else if (Recognizer.IsStaticMethod(converted, new Func <bool, bool>(Factors.Factor.Not)))
                    {
                        bool allArgumentsAreLiteral = mie.Arguments.All(arg => arg is ILiteralExpression);
                        if (allArgumentsAreLiteral)
                        {
                            return(Builder.LiteralExpr(evaluator.Evaluate(mie)));
                        }
                    }
                }
                foreach (IExpression arg in mie.Arguments)
                {
                    if (arg is IAddressOutExpression)
                    {
                        IAddressOutExpression iaoe = (IAddressOutExpression)arg;
                        IVariableDeclaration  ivd  = Recognizer.GetVariableDeclaration(iaoe.Expression);
                        if (ivd != null)
                        {
                            FactorManager.FactorInfo info = CodeRecognizer.GetFactorInfo(context, mie);
                            if (info != null && info.IsDeterministicFactor && !context.InputAttributes.Has <DerivedVariable>(ivd))
                            {
                                context.InputAttributes.Set(ivd, new DerivedVariable());
                            }
                        }
                    }
                }
            }
            return(converted);
        }
コード例 #32
0
        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);
        }
コード例 #33
0
 public virtual IExpression TransformVariableReferenceExpression(IVariableReferenceExpression value)
 {
     value.Variable = this.TransformVariableReference(value.Variable);
     return value;
 }