Beispiel #1
0
        private void CreateReducedVariableInformation(IVariableDeclaration ivd, HoistingInfo info)
        {
            int arrayDepth     = info.maxDepthWhereDimensionCouldMatter.Length;
            var varInfo        = VariableInformation.GetVariableInformation(context, ivd);
            var reducedVarInfo = VariableInformation.GetVariableInformation(context, info.newVariable);

            for (int bracket = 0; bracket < varInfo.sizes.Count; bracket++)
            {
                List <IExpression>          newSizes     = new List <IExpression>();
                List <IVariableDeclaration> newIndexVars = new List <IVariableDeclaration>();
                for (int dim = 0; dim < varInfo.sizes[bracket].Length; dim++)
                {
                    if (info.maxDepthWhereDimensionCouldMatter[bracket][dim] == arrayDepth)
                    {
                        newSizes.Add(varInfo.sizes[bracket][dim]);
                        if (varInfo.indexVars.Count > bracket && varInfo.indexVars[bracket].Length > dim)
                        {
                            newIndexVars.Add(varInfo.indexVars[bracket][dim]);
                        }
                    }
                }
                if (newSizes.Count > 0)
                {
                    reducedVarInfo.sizes.Add(newSizes.ToArray());
                    reducedVarInfo.indexVars.Add(newIndexVars.ToArray());
                }
            }
        }
Beispiel #2
0
        protected override IExpression ConvertArrayIndexer(IArrayIndexerExpression iaie)
        {
            var indices = Recognizer.GetIndices(iaie, out IExpression target);

            if (target is IVariableReferenceExpression)
            {
                // Only convert indices that could matter.
                IVariableDeclaration ivd  = Recognizer.GetVariableDeclaration(target);
                HoistingInfo         info = GetOrCreateHoistingInfo(ivd);
                int indexingDepth         = indices.Count;
                for (int bracket = 0; bracket < indexingDepth; bracket++)
                {
                    for (int dim = 0; dim < indices[bracket].Count; dim++)
                    {
                        if (info.maxDepthWhereDimensionCouldMatter.Length <= bracket ||
                            info.maxDepthWhereDimensionCouldMatter[bracket][dim] >= indexingDepth)
                        {
                            ConvertExpression(indices[bracket][dim]);
                        }
                    }
                }
                return(iaie);
            }
            else
            {
                return(base.ConvertArrayIndexer(iaie));
            }
        }
Beispiel #3
0
        private void SetDimensionMattersAtDepth(HoistingInfo info, int bracket, int dim, int depth)
        {
            var oldDepth = info.maxDepthWhereDimensionCouldMatter[bracket][dim];

            if (depth > oldDepth)
            {
                info.maxDepthWhereDimensionCouldMatter[bracket][dim] = depth;
                anyChanged = true;
            }
        }
Beispiel #4
0
        private HoistingInfo GetOrCreateHoistingInfo(IVariableDeclaration ivd)
        {
            HoistingInfo info;

            if (!infoOfVariable.TryGetValue(ivd, out info))
            {
                info = new HoistingInfo(VariableInformation.GetVariableInformation(context, ivd));
                infoOfVariable.Add(ivd, info);
            }
            return(info);
        }
Beispiel #5
0
        private bool IsReducibleAtDepth(HoistingInfo info, int depth)
        {
            int arrayDepth = info.maxDepthWhereDimensionCouldMatter.Length;

            for (int bracket = depth; bracket < info.maxDepthWhereDimensionCouldMatter.Length; bracket++)
            {
                for (int dim = 0; dim < info.maxDepthWhereDimensionCouldMatter[bracket].Length; dim++)
                {
                    if (info.maxDepthWhereDimensionCouldMatter[bracket][dim] != arrayDepth)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Beispiel #6
0
        private Type GetReducedType(Type type, HoistingInfo info)
        {
            int          arrayDepth = info.maxDepthWhereDimensionCouldMatter.Length;
            Stack <Type> stack      = new Stack <Type>();

            for (int bracket = 0; bracket < arrayDepth; bracket++)
            {
                stack.Push(type);
                type = Util.GetElementType(type);
            }
            Type reducedType = type;

            for (int bracket = arrayDepth - 1; bracket >= 0; bracket--)
            {
                Type originalType = stack.Pop();
                int  reducedRank  = info.maxDepthWhereDimensionCouldMatter[bracket].Count(d => d == arrayDepth);
                if (reducedRank > 0)
                {
                    reducedType = Util.ChangeElementTypeAndRank(originalType, reducedType, reducedRank);
                }
            }
            return(reducedType);
        }
Beispiel #7
0
        private void PromoteDimensions(HoistingInfo info)
        {
            int  arrayDepth = info.maxDepthWhereDimensionCouldMatter.Length;
            bool previousBracketMattersAtArrayDepth = false;

            for (int bracket = arrayDepth - 1; bracket >= 0; bracket--)
            {
                bool bracketMattersAtArrayDepth = false;
                for (int dim = 0; dim < info.maxDepthWhereDimensionCouldMatter[bracket].Length; dim++)
                {
                    int depth = info.maxDepthWhereDimensionCouldMatter[bracket][dim];
                    if (depth == arrayDepth)
                    {
                        bracketMattersAtArrayDepth = true;
                    }
                    else if (depth > 0 && previousBracketMattersAtArrayDepth)
                    {
                        info.maxDepthWhereDimensionCouldMatter[bracket][dim] = arrayDepth;
                        bracketMattersAtArrayDepth = true;
                    }
                }
                previousBracketMattersAtArrayDepth = bracketMattersAtArrayDepth;
            }
        }
Beispiel #8
0
        protected override IExpression ConvertAssign(IAssignExpression iae)
        {
            IExpression target;
            var         indices = Recognizer.GetIndices(iae.Target, out target);

            if (target is IVariableReferenceExpression || target is IVariableDeclarationExpression)
            {
                variablesInExpression.Clear();
                ConvertExpression(iae.Expression);
                IVariableDeclaration ivd  = Recognizer.GetVariableDeclaration(target);
                HoistingInfo         info = GetOrCreateHoistingInfo(ivd);
                int  depth          = indices.Count;
                bool rhsIsReducible = IsReducibleArrayCreateExpression(iae.Expression);
                if (!rhsIsReducible)
                {
                    bool rhsIsCopy = Recognizer.IsStaticGenericMethod(iae.Expression, new Func <PlaceHolder, PlaceHolder, PlaceHolder>(ArrayHelper.SetTo));
                    if (rhsIsCopy)
                    {
                        IMethodInvokeExpression imie = (IMethodInvokeExpression)iae.Expression;
                        var sourceExpr    = imie.Arguments[1];
                        var sourceIndices = Recognizer.GetIndices(sourceExpr, out IExpression source);
                        if (source is IVariableDeclaration)
                        {
                            IVariableDeclaration sourceVar  = Recognizer.GetVariableDeclaration(source);
                            HoistingInfo         sourceInfo = GetOrCreateHoistingInfo(sourceVar);
                            for (int bracket = indices.Count; bracket < info.maxDepthWhereDimensionCouldMatter.Length; bracket++)
                            {
                                int sourceBracket = sourceIndices.Count + bracket;
                                for (int dim = 0; dim < info.maxDepthWhereDimensionCouldMatter[bracket].Length; dim++)
                                {
                                    // the dimension matters if it matters in the source array.
                                    int sourceDepth = sourceInfo.maxDepthWhereDimensionCouldMatter[sourceBracket][dim];
                                    SetDimensionMattersAtDepth(info, bracket, dim, sourceDepth);
                                    depth = System.Math.Max(depth, sourceDepth);
                                }
                            }
                        }
                        else
                        {
                            rhsIsCopy = false;
                        }
                    }
                    if (!rhsIsCopy)
                    {
                        // all deeper dimensions matter
                        for (int bracket = indices.Count; bracket < info.maxDepthWhereDimensionCouldMatter.Length; bracket++)
                        {
                            for (int dim = 0; dim < info.maxDepthWhereDimensionCouldMatter[bracket].Length; dim++)
                            {
                                int arrayDepth = info.maxDepthWhereDimensionCouldMatter.Length;
                                SetDimensionMattersAtDepth(info, bracket, dim, arrayDepth);
                                depth = System.Math.Max(depth, arrayDepth);
                            }
                        }
                    }
                }
                // expand variablesInExpression based on correlations in the index expressions.
                // For example:
                //   array[i][index[i][j]] = j
                // depends on i and j.
                bool changed;
                do
                {
                    changed = false;
                    for (int bracket = 0; bracket < indices.Count; bracket++)
                    {
                        for (int dim = 0; dim < indices[bracket].Count; dim++)
                        {
                            var index     = indices[bracket][dim];
                            var indexVars = Recognizer.GetVariables(index).ToList();
                            if (variablesInExpression.ContainsAny(indexVars) && indexVars.Any(v => !variablesInExpression.Contains(v)))
                            {
                                variablesInExpression.AddRange(indexVars);
                                changed = true;
                            }
                        }
                    }
                } while (changed);
                for (int bracket = 0; bracket < indices.Count; bracket++)
                {
                    for (int dim = 0; dim < indices[bracket].Count; dim++)
                    {
                        var index = indices[bracket][dim];
                        if (index is IVariableReferenceExpression)
                        {
                            IVariableDeclaration indexVar = Recognizer.GetVariableDeclaration(index);
                            if (variablesInExpression.Contains(indexVar) || !unbrokenLoopVars.Contains(indexVar))
                            {
                                // index is used on rhs or the loop is broken, so the dimension matters.
                                SetDimensionMattersAtDepth(info, bracket, dim, depth);
                            }
                        }
                        else
                        {
                            // index is not a loop counter, so the dimension matters.
                            SetDimensionMattersAtDepth(info, bracket, dim, depth);
                        }
                    }
                }
                return(iae);
            }
            else
            {
                return(base.ConvertAssign(iae));
            }
        }
Beispiel #9
0
 protected override IExpression ConvertMethodInvoke(IMethodInvokeExpression imie)
 {
     if (imie.Arguments.Any(arg => arg is IAddressOutExpression))
     {
         Set <IVariableDeclaration> oldVariablesInExpression = (Set <IVariableDeclaration>)variablesInExpression.Clone();
         variablesInExpression.Clear();
         ConvertExpression(imie.Method);
         foreach (var arg in imie.Arguments)
         {
             if (!(arg is IAddressOutExpression))
             {
                 ConvertExpression(arg);
             }
         }
         foreach (var arg in imie.Arguments)
         {
             if (arg is IAddressOutExpression iaoe)
             {
                 var indices = Recognizer.GetIndices(iaoe.Expression, out IExpression target);
                 if (target is IVariableReferenceExpression || target is IVariableDeclarationExpression)
                 {
                     IVariableDeclaration ivd  = Recognizer.GetVariableDeclaration(target);
                     HoistingInfo         info = GetOrCreateHoistingInfo(ivd);
                     int arrayDepth            = info.maxDepthWhereDimensionCouldMatter.Length;
                     for (int bracket = 0; bracket < indices.Count; bracket++)
                     {
                         for (int dim = 0; dim < indices[bracket].Count; dim++)
                         {
                             var index = indices[bracket][dim];
                             if (index is IVariableReferenceExpression)
                             {
                                 IVariableDeclaration indexVar = Recognizer.GetVariableDeclaration(index);
                                 if (variablesInExpression.Contains(indexVar) || !unbrokenLoopVars.Contains(indexVar))
                                 {
                                     // index is used on rhs or the loop is broken, so the dimension matters.
                                     SetDimensionMattersAtDepth(info, bracket, dim, arrayDepth);
                                 }
                             }
                             else
                             {
                                 // index is not a loop counter, so the dimension matters.
                                 SetDimensionMattersAtDepth(info, bracket, dim, arrayDepth);
                             }
                         }
                     }
                     // all deeper dimensions matter
                     for (int bracket = indices.Count; bracket < arrayDepth; bracket++)
                     {
                         for (int dim = 0; dim < info.maxDepthWhereDimensionCouldMatter[bracket].Length; dim++)
                         {
                             SetDimensionMattersAtDepth(info, bracket, dim, arrayDepth);
                         }
                     }
                 }
             }
         }
         variablesInExpression.AddRange(oldVariablesInExpression);
         return(imie);
     }
     else
     {
         return(base.ConvertMethodInvoke(imie));
     }
 }