Пример #1
0
        public static BlockExpression GetInvariants(this IList <Expression> expressions, params ParameterExpression[] variables)
        {
            var invariants     = new List <Expression>();
            var invariantVars  = new List <ParameterExpression>();
            var vars           = new HashSet <ParameterExpression>(variables);
            var movedVariables = new List <ParameterExpression>();

            for (var i = 0; i < expressions.Count; i++)
            {
                var ei = expressions[i];

                if (ei is BlockExpression be)
                {
                    foreach (var ee in be.Expressions)
                    {
                        if (ee is BinaryExpression ae && ae.NodeType == ExpressionType.Assign)
                        {
                            var left = (ParameterExpression)ae.Left;
                            var eei  = DependencyChecker.FindInvariant(ae.Right, vars);
                            if (eei == ae.Right)
                            {
                                invariants.Add(ae);
                                invariantVars.Add(left);
                                ei = ExpressionReplacer.Replace(ei, ee, Expression.Empty());
                            }
                            else
                            {
                                var ee1 = ee;
                                vars.Add(left);
                                while (eei != null)
                                {
                                    var t = Expression.Parameter(eei.Type);
                                    invariants.Add(Expression.Assign(t, eei));
                                    invariantVars.Add(t);
                                    var ee2 = ExpressionReplacer.Replace(ee1, eei, t);
                                    ei  = ExpressionReplacer.Replace(ei, ee1, ee2);
                                    ee1 = ee2;
                                    eei = DependencyChecker.FindInvariant(ee1, vars);
                                }
                            }
                        }
                        else
                        {
                            var ee1 = ee;
                            var eei = DependencyChecker.FindInvariant(ee1, vars);
                            while (eei != null)
                            {
                                var t = Expression.Parameter(eei.Type);
                                invariants.Add(Expression.Assign(t, eei));
                                invariantVars.Add(t);
                                var ee2 = ExpressionReplacer.Replace(ee1, eei, t);
                                ei  = ExpressionReplacer.Replace(ei, ee1, ee2);
                                ee1 = ee2;
                                eei = DependencyChecker.FindInvariant(ee1, vars);
                            }
                        }
                    }
                }
Пример #2
0
        public static Expression EliminateCommonSubexpressions(this Expression expression, ref IEnumerable <ParameterExpression> variablePool)
        {
            var pool = new VariablePool(variablePool);

            do
            {
                var q = from e in ExpressionCounter.Evaluate(expression)
                        where e.Value.usageCount > 1 && e.Value.cost > 0
                        orderby e.Value.usageCount descending, e.Value.cost descending
                select e.Key;
                var mostExpensive = q.FirstOrDefault();
                if (mostExpensive == null)
                {
                    break;
                }
                // introduce a variable for mostExpensive
                var t = pool.GetVariable(mostExpensive.Type);
                // TODO: fix the order of the variables. Assignments should go after all depends
                expression = MergeBlocks(t, mostExpensive, ExpressionReplacer.Replace(expression, mostExpensive, t, new CodeComparer()));
            } while (true);
            variablePool = pool.Variables;
            return(expression);
        }