Exemplo n.º 1
0
        public void TestNoDeclare()
        {
            var i  = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));
            var sv = new ValSimple("5", typeof(int));
            var s1 = new StatementAssign(i, sv);

            Assert.IsTrue(s1.CodeItUp().First().Trim().StartsWith("aInt32_"), "Check for decl: " + s1.CodeItUp().First());
        }
Exemplo n.º 2
0
        public void TryCombineTwoNoneDeclaresDeclFound()
        {
            var i  = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));
            var sv = new ValSimple("5", typeof(int));
            var s1 = new StatementAssign(i, sv);
            var s2 = new StatementAssign(i, sv);

            Assert.IsTrue(s1.TryCombineStatement(s2, new DummyTrackingOptimizationService(true)), "Combine when no decl found");
        }
Exemplo n.º 3
0
        public void TestBasicCMValues()
        {
            var i  = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));
            var sv = new ValSimple("5", typeof(int));
            var s1 = new StatementAssign(i, sv);

            Assert.AreEqual(1, s1.ResultVariables.Count(), "# result variables");
            Assert.AreEqual(i.RawValue, s1.ResultVariables.First(), "the name");
            Assert.AreEqual(0, s1.DependentVariables.Count(), "no dependent variables");
        }
Exemplo n.º 4
0
        public void AssignDependents()
        {
            var p1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));
            var p2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));

            var v = new ValSimple($"{p2.RawValue}+10", typeof(int), new IDeclaredParameter[] { p2 });
            var a = new StatementAssign(p1, v);

            Assert.AreEqual(1, a.DependentVariables.Count());
            Assert.AreEqual(p2.RawValue, a.DependentVariables.First());
        }
Exemplo n.º 5
0
        public void TestCMValuesForSimpleExpression()
        {
            var i  = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));
            var di = DeclarableParameter.CreateDeclarableParameterExpression(typeof(double));
            var sv = new ValSimple("5", typeof(int), new IDeclaredParameter[] { di });
            var s1 = new StatementAssign(i, sv);

            Assert.AreEqual(1, s1.ResultVariables.Count(), "# result variables");
            Assert.AreEqual(i.RawValue, s1.ResultVariables.First(), "the name");
            Assert.AreEqual(1, s1.DependentVariables.Count(), "no dependent variables");
            Assert.AreEqual(di.RawValue, s1.DependentVariables.First(), "a dependent variable");
        }
Exemplo n.º 6
0
        public void TestCombineDifferentInitialValues()
        {
            IValue initial1 = new ValSimple("0", typeof(int));
            IValue initial2 = new ValSimple("1", typeof(int));
            IValue size     = new ValSimple("10", typeof(int));

            var lv1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));
            var lv2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));

            var p1 = new StatementForLoop(lv1, size, initial1);
            var p2 = new StatementForLoop(lv2, size, initial2);

            var r = p1.TryCombineStatement(p2, new dummyOpt());

            Assert.IsFalse(r, "different initial conditions, should be null");
        }
Exemplo n.º 7
0
        public void TestRememberEmbededConstExpr()
        {
            var gc = new GeneratedCode();
            var c1 = Expression.Constant(new ROOTNET.NTH1F("hi", "there", 100, 0.0, 10.0));
            var c2 = Expression.Constant(new ROOTNET.NTH1F("no", "way", 100, 0.0, 10.0));

            var n1 = Expression.Call(c1, typeof(ROOTNET.NTH1F).GetMethod("GetNbinsX"));
            var n2 = Expression.Call(c2, typeof(ROOTNET.NTH1F).GetMethod("GetNbinsX"));

            var r1 = new ValSimple("1", typeof(int));
            var r2 = new ValSimple("2", typeof(int));

            gc.RememberSubexpression(n1, r1);
            gc.RememberSubexpression(n2, r2);

            Assert.AreEqual(r1, gc.LookupSubexpression(n1), "lookup n1");
            Assert.AreEqual(r2, gc.LookupSubexpression(n2), "lookup n2");
        }
Exemplo n.º 8
0
        public void AggregateCombineWithRenameNoChance()
        {
            // a = a + b
            // c = c + b
            // These two should combine correctly, somehow.

            var a    = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));
            var ainc = new ValSimple(string.Format("{0}+b", a.ParameterName), typeof(int));
            var s1   = new StatementAggregate(a, ainc);

            var c    = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));
            var cinc = new ValSimple(string.Format("{0}+b", c.ParameterName), typeof(int));
            var s2   = new StatementAggregate(c, cinc);

            var opt    = new MyCodeOptimizer(false);
            var result = s1.TryCombineStatement(s2, opt);

            Assert.IsFalse(result, "Expected combination would work");
        }
Exemplo n.º 9
0
        /// <summary>
        /// We are looking at a&&b or a||b. We wnat to make sure we evaluate b iff we need it, depending on the result of a.
        /// </summary>
        /// <param name="expr"></param>
        /// <param name="ce"></param>
        /// <param name="cc"></param>
        /// <param name="container"></param>
        /// <returns></returns>
        /// <remarks>
        /// To prevent us from updating variables (which makes optmization harder), we will implement the code as follows for a&&b:
        /// bool_1 = false; bool_2 = false; bool_3 = false;
        /// bool_1 = a
        /// if (bool_1) bool_2 = b
        /// bool_3 = bool_1 && bool_2
        ///</remarks>
        private static IValue GetExpressionForBoolAndOr(Expression expr, IGeneratedQueryCode ce, ICodeContext cc, CompositionContainer container)
        {
            // Svae to make sure we can get back.
            var outterScope = ce.CurrentScope;

            // Create a variable to hold the result of this test
            var resultBool3 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(bool));

            resultBool3.InitialValue = new ValSimple("false", typeof(bool));
            ce.Add(resultBool3);

            // Create and evaluate bool_1
            var binaryExpression            = expr as BinaryExpression;
            DeclarableParameter resultBool1 = AssignExpreaaionToEvaluationIfNeededBool(ce, cc, container, binaryExpression.Left);

            // Now, see if we need to evalute the right hand operand.
            if (expr.NodeType == ExpressionType.AndAlso)
            {
                ce.Add(new Statements.StatementFilter(resultBool1));
            }
            else
            {
                var notYet = new ValSimple($"!{resultBool1.RawValue}", typeof(bool), new IDeclaredParameter[] { resultBool1 });
                ce.Add(new Statements.StatementFilter(notYet));
            }

            // Create and evaluate bool 1.
            var resultBool2 = AssignExpreaaionToEvaluationIfNeededBool(ce, cc, container, binaryExpression.Right, outterScope);

            ce.CurrentScope = outterScope;

            // Finally, evaluate bool3.
            var termEvaluation = expr.NodeType == ExpressionType.AndAlso
                ? $"{resultBool1.RawValue}&&{resultBool2.RawValue}"
                : $"{resultBool1.RawValue}||{resultBool2.RawValue}";

            ce.Add(new Statements.StatementAssign(resultBool3, new ValSimple(termEvaluation, typeof(bool), new[] { resultBool1, resultBool2 })));

            // Return the value we've now filled.
            return(resultBool3);
        }
Exemplo n.º 10
0
        public void AggregateCombineWithRename()
        {
            // a = a + b
            // c = c + b
            // These two should combine correctly, somehow.

            var a    = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));
            var ainc = new ValSimple(string.Format("{0}+b", a.ParameterName), typeof(int));
            var s1   = new StatementAggregate(a, ainc);

            var c    = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int));
            var cinc = new ValSimple(string.Format("{0}+b", c.ParameterName), typeof(int));
            var s2   = new StatementAggregate(c, cinc);

            var opt    = new MyCodeOptimizer(true);
            var result = s1.TryCombineStatement(s2, opt);

            Assert.IsTrue(result, "Expected combination would work");

            Assert.AreEqual(a.ParameterName, opt.NewVariable.ParameterName, "new name not renamed to");
            Assert.AreEqual(c.ParameterName, opt.OldName, "old name for rename not right");
        }
Exemplo n.º 11
0
        /// <summary>
        /// New a ROOT object. Make sure that it gets dtor'd!
        /// </summary>
        /// <param name="expression"></param>
        /// <param name="result"></param>
        /// <param name="gc"></param>
        /// <param name="context"></param>
        /// <param name="container"></param>
        /// <returns></returns>
        public Expression ProcessNew(NewExpression expression, out IValue result, IGeneratedQueryCode gc, CompositionContainer container)
        {
            ///
            /// Do checks
            ///

            if (gc == null)
            {
                throw new ArgumentException("gc");
            }
            if (expression == null)
            {
                throw new ArgumentNullException("expression");
            }

            ///
            /// Figure out the type. We can only get here if we get through ROOTNET.xxx
            ///

            result = null;
            string tname = expression.Type.FullName.Substring(8);

            if (tname[0] != 'N')
            {
                throw new ArgumentException(string.Format("Don't know how to translate to a ROOT type '{0}'", expression.Type.FullName));
            }
            tname = tname.Substring(1);

            ///
            /// We assume the include file "just works" - this is ROOT, after all. But lets hope.
            /// This is something we might have to deal with later. :-)
            ///

            gc.AddIncludeFile(string.Format("{0}.h", tname));

            ///
            /// Now, build the constructor, and add it to the statement list.
            ///

            var ctor     = new StringBuilder();
            var ctorName = expression.Type.CreateUniqueVariableName();

            ctor.AppendFormat("{0} {1}", tname, ctorName);

            var argDep = AddMethodArguments(expression.Arguments, gc, container, ctor).ToArray();

            gc.Add(new Statements.StatementSimpleStatement(ctor.ToString(), dependentVars: argDep.Select(i => i.RawValue).ToArray(), resultVars: new string[] { ctorName }));

            ///
            /// Now, everything in the C++ translation is a pointer, so we will
            /// not create a pointer to this guy.
            ///

            var ptrDecl = new StringBuilder();
            var ptrName = expression.Type.CreateUniqueVariableName();

            ptrDecl.AppendFormat("{0} *{1} = &{2}", tname, ptrName, ctorName);
            gc.Add(new Statements.StatementSimpleStatement(ptrDecl.ToString(), dependentVars: new string[] { ctorName }, resultVars: new string[] { ptrName }));

            ///
            /// That pointer is what we return for later use!
            ///

            result = new ValSimple(ptrName, expression.Type, argDep);
            return(expression);
        }
        /// <summary>
        /// Translate the method call
        /// </summary>
        /// <param name="expr"></param>
        /// <param name="result"></param>
        /// <param name="gc"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public IValue CodeMethodCall(MethodCallExpression expr, IGeneratedQueryCode gc, CompositionContainer container)
        {
            Init();

            ///
            /// First see if we can't locate the method call that at least matches in names
            ///

            var matchingMethodNames = from kt in _knownTypes
                                      where kt.Name == expr.Method.DeclaringType.Name
                                      from m in kt.Methods
                                      where m.Name == expr.Method.Name
                                      select new
            {
                theType   = kt,
                theMethod = m
            };

            ///
            /// Next, match with the arguments
            ///

            var matchingMethod = from m in matchingMethodNames
                                 where m.theMethod.Arguments.Length == expr.Arguments.Count
                                 where m.theMethod.Arguments.Zip(expr.Arguments, (us, them) => new Tuple <KnownTypeInfo.MechodArg, Expression>(us, them)).All(apair => apair.Item1.Type == apair.Item2.Type.FullName)
                                 select m;

            ///
            /// Ok, at this point, we should have only one guy. If we have more then just choose the first
            ///

            var method = matchingMethod.FirstOrDefault();

            if (method == null)
            {
                throw new ArgumentException("Could not find a matching method to translate for the call " + expr.ToString());
            }

            ///
            /// And now translate the call
            ///

            StringBuilder rawValue = new StringBuilder();

            rawValue.Append(method.theMethod.CPPName);
            rawValue.Append("(");
            bool first      = true;
            var  dependents = Enumerable.Empty <IDeclaredParameter>();

            foreach (var arg in expr.Arguments.Zip(method.theMethod.Arguments, (m, a) => Tuple.Create(m, a)))
            {
                if (!first)
                {
                    rawValue.Append(",");
                }
                first = false;
                var e = ExpressionToCPP.InternalGetExpression(arg.Item1, gc, null, container);
                rawValue.AppendFormat("({0}){1}", arg.Item2.CPPType, e.RawValue);
                dependents = dependents.Concat(e.Dependants);
            }
            rawValue.Append(")");

            var result = new ValSimple(rawValue.ToString(), expr.Type, dependents);

            ///
            /// Include files
            ///

            foreach (var ifile in method.theMethod.IncludeFiles)
            {
                gc.AddIncludeFile(ifile);
            }

            ///
            /// We aren't re-writing this expression, so just return it.
            ///

            return(result);
        }
Exemplo n.º 13
0
        /// <summary>
        /// Build a code statement from the include files, the expression for the method call, and the generated lines of code.
        /// </summary>
        /// <param name="expr"></param>
        /// <param name="gc"></param>
        /// <param name="container"></param>
        /// <param name="includeFiles"></param>
        /// <param name="loc"></param>
        /// <returns></returns>
        public static IValue BuildCPPCodeStatement(MethodCallExpression expr, IGeneratedQueryCode gc, CompositionContainer container, string[] includeFiles, string[] loc)
        {
            // Get include files in.
            if (includeFiles != null)
            {
                foreach (var inc in includeFiles)
                {
                    gc.AddIncludeFile(inc);
                }
            }

            // Next, go after the lines of code. We have to first sort out what parameter names we are looking at,
            // and then force a translation of those parameters into simple values we can pass to the C++ code we
            // are going to pull back.
            var paramsTranslated = from p in expr.Arguments.Zip(expr.Method.GetParameters(), (arg, param) => Tuple.Create(arg, param))
                                   select new
            {
                Name       = p.Item2.Name,
                Translated = ExpressionToCPP.InternalGetExpression(p.Item1, gc, null, container)
            };
            var paramLookup = paramsTranslated.ToDictionary(v => v.Name, v => v.Translated.ApplyParensIfNeeded());

            // Parse out the list of variables that are used. We will be passing these up the line as needed
            // so that we can tell how to optimize things.
            var dependents = new HashSet <string>(FindDeclarableParameters.FindAll(expr).Select(e => e.RawValue));

            // We also need a return variable. Since this can be multiple lines of code and we don't
            // know how the result will be used, we have to declare it up front... and pray they
            // use it correctly! :-)

            var cppResult = DeclarableParameter.CreateDeclarableParameterExpression(expr.Type);

            var cppStatement = new CPPCodeStatement(expr.Method, cppResult, loc, dependents);

            gc.Add(cppStatement);
            gc.Add(cppResult);

            paramLookup.Add(expr.Method.Name, cppResult.RawValue);

            var result = new ValSimple(cppResult.RawValue, expr.Type, DeclarableParameter.CreateDeclarableParameterExpression(cppResult.RawValue, expr.Type).AsArray());

            // Make sure a result exists in here! This at least will prevent some bad C++ code from getting generated!
            var  lookForResult = new Regex(string.Format(@"\b{0}\b", expr.Method.Name));
            bool didReference  = loc.Any(l => lookForResult.Match(l).Success);

            if (!didReference)
            {
                throw new ArgumentException(string.Format("The C++ code attached to the method '{0}' doesn't seem to set a result.", expr.Method.Name));
            }

            // Figure out if there are any Unique variables. If there are, then we need to do
            // a replacement on them.
            var findUnique        = new Regex(@"\b\w*Unique\b");
            var varUniqueRequests = (from l in loc
                                     let matches = findUnique.Matches(l)
                                                   from m in Enumerable.Range(0, matches.Count)
                                                   select matches[m].Value).Distinct();

            foreach (var varRepl in varUniqueRequests)
            {
                var uniqueName       = varRepl.Substring(0, varRepl.Length - "Unique".Length);
                var uniqueTranslated = uniqueName + _uniqueCounter.ToString();
                cppStatement.AddUniqueVariable(varRepl, uniqueTranslated);
                _uniqueCounter++;
            }

            // Add the parameters that need to be translated here.
            foreach (var paramName in paramLookup)
            {
                cppStatement.AddParamReplacement(paramName.Key, paramName.Value);
            }

            return(result);
        }