public void TestCombineNestedForLoopOnOneSide() { var base1 = new StatementInlineBlock(); var limit = new LINQToTTreeLib.Variables.ValSimple("5", typeof(int)); var loopP1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var loop1 = new StatementForLoop(loopP1, limit); base1.Add(loop1); var base2 = new StatementInlineBlock(); var limit2 = new LINQToTTreeLib.Variables.ValSimple("5", typeof(int)); var loopP12 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var loop12 = new StatementForLoop(loopP12, limit); base2.Add(loop12); var loopP22 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var loop22 = new StatementForLoop(loopP22, limit); loop12.Add(loop22); var r = base1.TryCombineStatement(base2, new dummyOpt()); Assert.IsTrue(r, "combination should work"); Assert.AreEqual(base1, loop1.Parent, "loop 1 parent"); Assert.AreEqual(loop1, loop22.Parent, "Loop 2 parent"); }
public void ValSimpleWithDependents() { var d = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var v = new ValSimple($"5+{d.RawValue}", typeof(int), new IDeclaredParameter[] { d }); Assert.IsNotNull(v.Dependants); Assert.AreEqual(1, v.Dependants.Count()); }
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()); }
public void ArrayReturnFromFunction() { var method = typeof(helperFunctions).GetMethod("CallMe"); var callExpr = Expression.Call(null, method); var result = new ValSimple("main", typeof(float[])); Assert.AreEqual("main", result.AsObjectReference(callExpr)); }
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"); }
public void TestParameterArrayObj() { var sv = new ValSimple("main", typeof(int[])); var p = Expression.Parameter(typeof(int[]), "main"); var r = Expression.Constant(1); var arr = Expression.ArrayIndex(p, r); Assert.AreEqual("main", sv.AsObjectReference(arr), "deref param"); }
public void TestParameterArray() { var sv = new ValSimple("main", typeof(int[])); var p = Expression.Parameter(typeof(int[]), "main"); var r = Expression.Constant(1); var arr = Expression.ArrayIndex(p, r); Assert.AreEqual("main", sv.CastToType(p), "Expression cast of parameter"); }
public void ValSimpleRenameWithDependents() { var d = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var v = new ValSimple($"5+{d.RawValue}", typeof(int), new IDeclaredParameter[] { d }); v.RenameRawValue(d.RawValue, "my_go_1"); Assert.AreEqual("5+my_go_1", v.RawValue); Assert.AreEqual("my_go_1", v.Dependants.First().RawValue); }
public void TestRememberExprSimpleByVal() { var gc = new GeneratedCode(); var expr = Expression.Constant(10); var r = new LINQToTTreeLib.Variables.ValSimple("10", typeof(int)); gc.RememberSubexpression(expr, r); Assert.AreEqual(r, gc.LookupSubexpression(Expression.Constant(10)), "Could not find expression"); }
public void TestRememberConstantObject() { var gc = new GeneratedCode(); var expr = Expression.Constant(new ROOTNET.NTH1F()); var r1 = new LINQToTTreeLib.Variables.ValSimple("10", typeof(int)); gc.RememberSubexpression(expr, r1); Assert.AreEqual(r1, gc.LookupSubexpression(expr), "Constant Expressions of arbitrary objects can't be looked up"); }
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"); }
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"); }
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"); }
public void TestRememberExprPop() { var gc = new GeneratedCode(); var initialScope = gc.CurrentScope; gc.Add(new StatementInlineBlock()); var expr = Expression.Constant(10); var r = new LINQToTTreeLib.Variables.ValSimple("10", typeof(int)); gc.RememberSubexpression(expr, r); gc.CurrentScope = initialScope; Assert.IsNull(gc.LookupSubexpression(Expression.Constant(10)), "Expression after popping"); }
public string CastToType(int sourceTypeSpec, int destTypeSpec) { IValue sourceType = null; switch (sourceTypeSpec) { case 0: sourceType = new ValSimple("10", typeof(int)); break; case 1: sourceType = new ValSimple("10.0", typeof(double)); break; default: return(""); } Type destType = null; switch (destTypeSpec) { case 0: destType = typeof(int); break; case 1: destType = typeof(double); break; default: return(""); } string result = VarUtils.CastToType(sourceType, Expression.Variable(destType, "d")); if (destType == sourceType.Type || sourceType.Type == typeof(float) && destType == typeof(double)) { Assert.IsFalse(result.Contains("(("), "More that '((' in the list of items ('" + result + "')"); } else { Assert.IsTrue(result.Contains("(("), "Incorrect number of '((' in the list of items ('" + result + "') - expecting a cast from '" + sourceType.Type.Name + " to " + destType.Name + "'!"); } return(result); }
public void TestRememberExprHideAndSeek() { var gc = new GeneratedCode(); var expr = Expression.Constant(5); var r1 = new LINQToTTreeLib.Variables.ValSimple("10", typeof(int)); gc.RememberSubexpression(expr, r1); var initialScope = gc.CurrentScope; gc.Add(new StatementInlineBlock()); var r2 = new LINQToTTreeLib.Variables.ValSimple("11", typeof(int)); gc.RememberSubexpression(expr, r2); Assert.AreEqual(r2, gc.LookupSubexpression(expr), "Is hidden one done right?"); gc.Pop(); Assert.AreEqual(r1, gc.LookupSubexpression(expr), "Is revealed one done right?"); }
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"); }
public void TestCombineNestedForLoop() { var limit = new LINQToTTreeLib.Variables.ValSimple("5", typeof(int)); var loopP1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var loop1 = new StatementForLoop(loopP1, limit); var loopP2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var loop2 = new StatementForLoop(loopP2, limit); loop1.Add(loop2); var limit2 = new LINQToTTreeLib.Variables.ValSimple("5", typeof(int)); var loopP12 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var loop12 = new StatementForLoop(loopP12, limit); var loopP22 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var loop22 = new StatementForLoop(loopP22, limit); loop12.Add(loop22); var r = loop1.TryCombineStatement(loop12, new dummyOpt()); Assert.IsTrue(r, "combination should work"); Assert.IsNull(loop1.Parent, "loop 1 parent"); Assert.AreEqual(loop1, loop2.Parent, "Loop 2 parent"); }
/// <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; }
public void LiftLoopInvarient() { var v = new GeneratedCode(); var limit = new LINQToTTreeLib.Variables.ValSimple("5", typeof(int)); var loopP1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var loop1 = new StatementForLoop(loopP1, limit); v.Add(loop1); var p2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var assign1 = new StatementAssign(p2, new ValSimple("f", typeof(int))); loop1.Add(p2); loop1.Add(assign1); Console.WriteLine("Unoptimized:"); v.DumpCodeToConsole(); StatementLifter.Optimize(v); Console.WriteLine(""); Console.WriteLine("Optimized:"); v.DumpCodeToConsole(); Assert.AreEqual(0, loop1.Statements.Count()); }
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"); }
public string CastToType(int sourceTypeSpec, int destTypeSpec) { IValue sourceType = null; switch (sourceTypeSpec) { case 0: sourceType = new ValSimple("10", typeof(int)); break; case 1: sourceType = new ValSimple("10.0", typeof(double)); break; default: return ""; } Type destType = null; switch (destTypeSpec) { case 0: destType = typeof(int); break; case 1: destType = typeof(double); break; default: return ""; } string result = VarUtils.CastToType(sourceType, Expression.Variable(destType, "d")); if (destType == sourceType.Type || sourceType.Type == typeof(float) && destType == typeof(double)) { Assert.IsFalse(result.Contains("(("), "More that '((' in the list of items ('" + result + "')"); } else { Assert.IsTrue(result.Contains("(("), "Incorrect number of '((' in the list of items ('" + result + "') - expecting a cast from '" + sourceType.Type.Name + " to " + destType.Name + "'!"); } return result; }
/// <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; }
public void TestRememberExprSimpleByVal() { var gc = new GeneratedCode(); var expr = Expression.Constant(10); var r = new LINQToTTreeLib.Variables.ValSimple("10", typeof(int)); gc.RememberSubExpression(expr, r); Assert.AreEqual(r, gc.LookupSubExpression(Expression.Constant(10)), "Could not find expression"); }
public void TestRememberExprPop() { var gc = new GeneratedCode(); var initialScope = gc.CurrentScope; gc.Add(new StatementInlineBlock()); var expr = Expression.Constant(10); var r = new LINQToTTreeLib.Variables.ValSimple("10", typeof(int)); gc.RememberSubExpression(expr, r); gc.CurrentScope = initialScope; Assert.IsNull(gc.LookupSubExpression(Expression.Constant(10)), "Expression after popping"); }
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"); }
public void TestRememberExprHideAndSeek() { var gc = new GeneratedCode(); var expr = Expression.Constant(5); var r1 = new LINQToTTreeLib.Variables.ValSimple("10", typeof(int)); gc.RememberSubExpression(expr, r1); var initialScope = gc.CurrentScope; gc.Add(new StatementInlineBlock()); var r2 = new LINQToTTreeLib.Variables.ValSimple("11", typeof(int)); gc.RememberSubExpression(expr, r2); Assert.AreEqual(r2, gc.LookupSubExpression(expr), "Is hidden one done right?"); gc.Pop(); Assert.AreEqual(r1, gc.LookupSubExpression(expr), "Is revealed one done right?"); }
public void RenameMethodCall() { var target = new ValSimple("(*aNTH1F_1233).Fill(((double)aInt32_326),1.0*((1.0*1.0)*1.0))", typeof(int)); target.RenameRawValue("aInt32_326", "aInt32_37"); Assert.AreEqual("(*aNTH1F_1233).Fill(((double)aInt32_37),1.0*((1.0*1.0)*1.0))", target.RawValue); }
public void AssignRenameDependents() { 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); a.RenameVariable(p2.RawValue, "aInt_1234"); Assert.AreEqual(1, a.DependentVariables.Count()); Assert.AreEqual("aInt_1234", a.DependentVariables.First()); }
public void ValSimpleNullDependents() { var v = new ValSimple("5", typeof(int), null); Assert.IsNotNull(v.Dependants); Assert.AreEqual(0, v.Dependants.Count()); }
public void LiftNoSideEffectFromNestedIdenticalLoops() { var v = new GeneratedCode(); var limit = new LINQToTTreeLib.Variables.ValSimple("10", typeof(int)); var loopP1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var loop1 = new StatementForLoop(loopP1, limit); v.Add(loop1); var loopP2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var loop2 = new StatementForLoop(loopP2, limit); v.Add(loop2); v.Add(new StatementWithNoSideEffects()); Console.WriteLine("Unoptimized:"); v.DumpCodeToConsole(); StatementLifter.Optimize(v); Console.WriteLine(""); Console.WriteLine("Optimized:"); v.DumpCodeToConsole(); // Check to see if it got lifted. Assert.AreEqual(1, v.CodeBody.Statements.WhereCast<IStatement, StatementWithNoSideEffects>().Count(), "#of no side effect statements"); }
public void TestRememberTwoSameConstantObjects() { var gc = new GeneratedCode(); var expr1 = Expression.Constant(new ROOTNET.NTH1F()); var expr2 = Expression.Constant(new ROOTNET.NTH1F()); var r1 = new LINQToTTreeLib.Variables.ValSimple("10", typeof(int)); var r2 = new LINQToTTreeLib.Variables.ValSimple("11", typeof(int)); gc.RememberSubExpression(expr1, r1); gc.RememberSubExpression(expr2, r2); Assert.AreEqual(r1, gc.LookupSubExpression(expr1), "expr1 failure"); Assert.AreEqual(r2, gc.LookupSubExpression(expr2), "expr2 failure"); }
public void TestRememberConstantObject() { var gc = new GeneratedCode(); var expr = Expression.Constant(new ROOTNET.NTH1F()); var r1 = new LINQToTTreeLib.Variables.ValSimple("10", typeof(int)); gc.RememberSubExpression(expr, r1); Assert.AreEqual(r1, gc.LookupSubExpression(expr), "Constant Expressions of arbitrary objects can't be looked up"); }