public void CombineFilterAtSameLevelWithDifferentStatements() { // Two if statements with same "if", at the same level, and combine second with first. // Next, we will do the two common ones. var f1 = new StatementFilter(new ValSimple("f1", typeof(bool))); var f2 = new StatementFilter(new ValSimple("f1", typeof(bool))); var p1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var p2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var a1 = new StatementAssign(p1, new ValSimple("5", typeof(int))); var a2 = new StatementAssign(p2, new ValSimple("15", typeof(int))); f1.Add(a1); f1.Add(p1); f2.Add(a2); f2.Add(p2); Console.WriteLine("Before optimization:"); foreach (var l in f1.CodeItUp()) { Console.WriteLine(l); } Assert.IsTrue(f1.TryCombineStatement(f2, null), "Two of the same if statements, and the combine should have worked"); Console.WriteLine("After optimization:"); foreach (var l in f1.CodeItUp()) { Console.WriteLine(l); } Assert.AreEqual(2, f1.Statements.Count()); }
public void CombineFilterWithHiddenBehindIf() { // Seen in the wild. We have two identical if statements, one outside, and one inside another // (different) if statement. It is OK to combine these two as the code is identical. // See test CombineFilterWithHiddenBehindIfAndExtraStatements for the case where at // least one statement needs to be left behind. // Top level guy. This is the unique filter statement. var filterUnique = new StatementFilter(new ValSimple("fUnique", typeof(bool))); // Next, we will do the two common ones. var f1 = new StatementFilter(new ValSimple("f1", typeof(bool))); var f2 = new StatementFilter(new ValSimple("f1", typeof(bool))); var p = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var a1 = new StatementAssign(p, new ValSimple("5", typeof(int))); var a2 = new StatementAssign(p, new ValSimple("5", typeof(int))); f1.Add(p); f2.Add(p); f1.Add(a1); f2.Add(a2); filterUnique.Add(f1); Assert.IsTrue(f2.TryCombineStatement(f1, null), "Two of the same if statements, but the target is at a higher level than the merge"); Assert.AreEqual(1, f2.Statements.Count()); }
public void CombineOneTwoLevelAndOneOneLevelFunctions2() { var q1 = new GeneratedCode(); var q2 = new GeneratedCode(); var f1 = QMFuncUtils.GenerateFunction(); var r1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var s1 = new Statements.StatementAssign(r1, new Variables.ValSimple(f1.Name + "()", typeof(int))); var f2 = GenerateFunction2(); var r2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var s2 = new Statements.StatementAssign(r2, new Variables.ValSimple(f2[1].Name + "()", typeof(int))); q1.Add(f1); q1.Add(s1); q1.SetResult(r1); q2.Add(f2[0]); q2.Add(f2[1]); q2.Add(s2); q2.SetResult(r2); var target = new CombinedGeneratedCode(); target.AddGeneratedCode(q1); target.AddGeneratedCode(q2); target.DumpCodeToConsole(); Assert.AreEqual(2, target.Functions.Count(), "# of functions should be combined to 2"); Assert.AreEqual(1, target.QueryCode().Count(), "# of query code blocks"); Assert.AreEqual(2, target.QueryCode().First().Statements.Count(), "# of statements in the combined block."); Assert.IsFalse(target.DumpCode().Where(l => l.Contains(f2[0].Name)).Any(), "The new function was still in there"); }
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 CombineFilterWithHiddenBehindIfAndExtraIndependentStatements() { // Seen in the wild. We have two identical if statements, one outside, and one inside another // (different) if statement. It is OK to combine these two as the code is identical. // See test CombineFilterWithHiddenBehindIfAndExtraStatements for the case where at // least one statement needs to be left behind. // Top level guy. This is the unique filter statement. var filterUnique = new StatementFilter(new ValSimple("fUnique", typeof(bool))); // Next, we will do the two common ones. var f1 = new StatementFilter(new ValSimple("f1", typeof(bool))); var f2 = new StatementFilter(new ValSimple("f1", typeof(bool))); var p1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var p2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var a1 = new StatementAssign(p1, new ValSimple("5", typeof(int))); var a2 = new StatementAssign(p2, new ValSimple("5", typeof(int))); f1.Add(a1); f1.Add(p1); f2.Add(a2); f2.Add(p2); // Now, a unique assignment. This can't be lifted b.c. it is hidden behind a different if statement in // the outside (the filterUnique). var pSpecial = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var aUnique = new StatementAssign(pSpecial, new ValSimple("10", typeof(int))); f1.Add(aUnique); f1.Add(pSpecial); filterUnique.Add(f1); var topLevel1 = new StatementInlineBlock(); var topLevel2 = new StatementInlineBlock(); topLevel1.Add(filterUnique); topLevel2.Add(f2); Console.WriteLine("Before optimization (target):"); topLevel2.DumpCodeToConsole(); Console.WriteLine("Before optimization (merge):"); topLevel1.DumpCodeToConsole(); // The combine should fail. Assert.IsFalse(f2.TryCombineStatement(f1, null), "The two are different if statements, so it should have failed"); Console.WriteLine("After optimization (target):"); topLevel2.DumpCodeToConsole(); Console.WriteLine("After optimization (merge):"); topLevel1.DumpCodeToConsole(); // Nothing should have been touched in f1 - double check. Assert.AreEqual(2, f1.Statements.Count()); }
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"); }
Tuple<IDeclaredParameter, IStatement> CreateAssignStatement(IValue valToAssign, IDeclaredParameter p1 = null) { if (p1 == null) { p1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); } IStatement s1 = new StatementAssign(p1, valToAssign); return Tuple.Create(p1, s1); }
/// <summary> /// Helper to create an assignment to a constant. /// </summary> /// <returns></returns> Tuple<IDeclaredParameter, IStatement> CreateConstAssignStatement(IDeclaredParameter p1 = null) { if (p1 == null) { p1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); } IStatement s1 = new StatementAssign(p1, new ValSimple("5", typeof(int))); return Tuple.Create(p1, s1); }
public void CombineFilterWithHiddenBehindIfAndExtraIndependentStatementsAndDeclaredVariables() { // When we try and fail to combine if statements, make sure we don't leave dangling name // changes - that the declaration aren't totally renamed. // Top level guy. This is the unique filter statement. var filterUnique = new StatementFilter(new ValSimple("fUnique", typeof(bool))); // Next, we will do the two common ones. var f1 = new StatementFilter(new ValSimple("f1", typeof(bool))); var f2 = new StatementFilter(new ValSimple("f1", typeof(bool))); var p1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var p2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); f1.Add(p1); f2.Add(p2); var a1 = new StatementAssign(p1, new ValSimple("5", typeof(int))); var a2 = new StatementAssign(p2, new ValSimple("5", typeof(int))); f1.Add(a1); f2.Add(a2); // Now, a unique assignment. This can't be lifted b.c. it is hidden behind a different if statement in // the outside (the filterUnique). var pSpecial = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var aUnique = new StatementAssign(pSpecial, new ValSimple("10", typeof(int))); f1.Add(pSpecial); f1.Add(aUnique); filterUnique.Add(f1); var topLevel1 = new StatementInlineBlock(); var topLevel2 = new StatementInlineBlock(); topLevel1.Add(filterUnique); topLevel2.Add(f2); Console.WriteLine("Before optimization (target):"); topLevel2.DumpCodeToConsole(); Console.WriteLine("Before optimization (merge):"); topLevel1.DumpCodeToConsole(); // The combine should fail. Assert.IsFalse(f2.TryCombineStatement(f1, null), "The two are different if statements, so it should have failed"); Console.WriteLine("After optimization (target):"); topLevel2.DumpCodeToConsole(); Console.WriteLine("After optimization (merge):"); topLevel1.DumpCodeToConsole(); // Nothing should have been touched in f1 - double check. Assert.AreEqual(2, f1.Statements.Count()); Assert.AreEqual(2, f1.DeclaredVariables.Count()); }
public void CombineFilterWithHiddenBehindIfAndExtraDependentStatements() { // When we move an if statement, if there are extra statements and they depend on the code // we want to move, then we can't move them. // Top level guy. This is the unique filter statement. var filterUnique = new StatementFilter(new ValSimple("fUnique", typeof(bool))); // Next, we will do the two common ones. var f1 = new StatementFilter(new ValSimple("f1", typeof(bool))); var f2 = new StatementFilter(new ValSimple("f1", typeof(bool))); var p = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var a1 = new StatementAssign(p, new ValSimple("5", typeof(int))); var a2 = new StatementAssign(p, new ValSimple("5", typeof(int))); f1.Add(a1); f1.Add(p); f2.Add(a2); f2.Add(p); // Now, a unique assignment. This can't be lifted b.c. it is hidden behind a different if statement in // the outside (the filterUnique). var pSpecial = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var aUnique = new StatementAssign(pSpecial, p); f1.Add(aUnique); f1.Add(pSpecial); filterUnique.Add(f1); var topLevel = new StatementInlineBlock(); topLevel.Add(filterUnique); topLevel.Add(f2); Console.WriteLine("Before optimization:"); foreach (var l in topLevel.CodeItUp()) { Console.WriteLine(l); } // The combine should fail. Assert.IsFalse(f2.TryCombineStatement(f1, null), "The two are different if statements, so it should have failed"); Console.WriteLine("After optimization:"); foreach (var l in topLevel.CodeItUp()) { Console.WriteLine(l); } // But some statements should have been moved! (note that f1 normally has two statements). Assert.AreEqual(2, f1.Statements.Count()); Assert.AreEqual(1, f2.Statements.Count()); }
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 TestCombineWithAlteredValue() { // This variable will be modified in an assignment statement. var varToBeModified = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var statementModifier = new StatementAssign(varToBeModified, new ValSimple("1", typeof(int))); // Next, we access this variable in an if statement. var finalVar = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var assignment = new StatementAssign(finalVar, varToBeModified); var checkVar = DeclarableParameter.CreateDeclarableParameterExpression(typeof(bool)); var ifUsesModifiedValue = new StatementFilter(new ValSimple(checkVar.RawValue, typeof(bool))); ifUsesModifiedValue.Add(assignment); var ifNoUsesModifiedValue = new StatementFilter(new ValSimple(checkVar.RawValue, typeof(bool))); // Ok, now create the two sets of top level statements. var blockWithModified = new StatementInlineBlock(); var blockWithoutModified = new StatementInlineBlock(); blockWithModified.Add(varToBeModified); blockWithModified.Add(finalVar); blockWithModified.Add(statementModifier); blockWithModified.Add(checkVar); blockWithoutModified.Add(checkVar); blockWithModified.Add(ifUsesModifiedValue); blockWithoutModified.Add(ifNoUsesModifiedValue); // Combine var r = blockWithoutModified.TryCombineStatement(blockWithModified, null); Assert.IsTrue(r, "try combine result"); foreach (var s in blockWithoutModified.CodeItUp()) { System.Diagnostics.Trace.WriteLine(s); } // Make sure the checkVar guy comes after the modified statement. var topLevelStatementForAssign = findStatementThatContains(blockWithoutModified, assignment); var posOfUse = findStatementIndex(blockWithoutModified, topLevelStatementForAssign); var posOfMod = findStatementIndex(blockWithoutModified, statementModifier); Assert.IsTrue(posOfMod < posOfUse, string.Format("Modification happens after use. modification: {0} use {1}", posOfMod, posOfUse)); }
public void DeclarationsAreMovedCorrectlyWhenStatementsReassigned() { // In this new world of moving things around, we move declaration and statements, but they aren't really connected. // So we should make sure that declaration aren't moved accidentally when they shouldn't be. // Inline block at the top var topLevel1 = new StatementInlineBlock(); var topLevel2 = new StatementInlineBlock(); // Top level guy. This is the unique filter statement. var filterUnique = new StatementFilter(new ValSimple("fUnique", typeof(bool))); topLevel1.Add(filterUnique); // Next, we will do the two common ones. var f1 = new StatementFilter(new ValSimple("f1", typeof(bool))); var f2 = new StatementFilter(new ValSimple("f1", typeof(bool))); var p1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var p2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); filterUnique.Add(p1); topLevel2.Add(p2); var a1 = new StatementAssign(p1, new ValSimple("5", typeof(int))); var a2 = new StatementAssign(p2, new ValSimple("5", typeof(int))); f1.Add(a1); f2.Add(a2); filterUnique.Add(f1); topLevel2.Add(f2); Console.WriteLine("Before optimization (target):"); topLevel2.DumpCodeToConsole(); Console.WriteLine("Before optimization (what is being merged):"); topLevel1.DumpCodeToConsole(); Assert.IsTrue(f2.TryCombineStatement(f1, null), "Two of the same if statements, and the combine should have worked"); Console.WriteLine("After optimization:"); foreach (var l in topLevel2.CodeItUp()) { Console.WriteLine(l); } Assert.AreEqual(1, f2.Statements.Count()); }
/// <summary> /// Generate a function with no arguments that returns an int given that name. The /// actual statement is a very simple constant. /// </summary> /// <param name="fname"></param> /// <returns></returns> public static QMFuncSource GenerateFunction() { int[] ints = new int[10]; var qmb = new QueryModelBuilder(); qmb.AddClause(new MainFromClause("i", typeof(int), Expression.Constant(ints))); qmb.AddClause(new SelectClause(Expression.Constant(1))); qmb.AddResultOperator(new Remotion.Linq.Clauses.ResultOperators.CountResultOperator()); var h = new QMFuncHeader() { Arguments = new object[] { }, QM = qmb.Build() }; h.QMText = h.QM.ToString(); var f = new QMFuncSource(h); var p = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var st = new StatementAssign(p, new ValSimple("5", typeof(int))); var inlineblock = new StatementInlineBlock(); inlineblock.Add(st); inlineblock.Add(new StatementReturn(p)); f.SetCodeBody(inlineblock); return f; }
public void DeclarationsAreIgnoredDuringLowerLevelMove() { // In this new world of moving things around, we move declaration and statements, but they aren't really connected. // So we should make sure that declaration aren't moved accidentally when they shouldn't be. // Inline block at the top var topLevel1 = new StatementInlineBlock(); var topLevel2 = new StatementInlineBlock(); // Top level guy. This is the unique filter statement. var filterUnique = new StatementFilter(new ValSimple("fUnique", typeof(bool))); topLevel1.Add(filterUnique); // Next, we will do the two common ones. var f1 = new StatementFilter(new ValSimple("f1", typeof(bool))); var f2 = new StatementFilter(new ValSimple("f1", typeof(bool))); var p = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); topLevel1.Add(p); topLevel2.Add(p); var a1 = new StatementAssign(p, new ValSimple("5", typeof(int))); var a2 = new StatementAssign(p, new ValSimple("5", typeof(int))); f1.Add(a1); f2.Add(a2); filterUnique.Add(f1); topLevel2.Add(f2); Console.WriteLine("Before optimization (target):"); topLevel1.DumpCodeToConsole(); Console.WriteLine("After optimization (merge):"); topLevel2.DumpCodeToConsole(); Assert.IsFalse(f1.TryCombineStatement(f2, null), "Two of the same if statements, but the one to be merged is not hidden behind other if statements!"); Assert.AreEqual(1, f1.Statements.Count()); Assert.AreEqual(1, f2.Statements.Count()); }
public void AssignEquivalentSameAfterReplacementWith2Vars() { var p1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var d1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var d2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var d3 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var d4 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var s1 = new StatementAssign(p1, new ValSimple($"{d1.RawValue}+{d2.RawValue}", typeof(int), new IDeclaredParameter[] { d1, d2 })); var s2 = new StatementAssign(p1, new ValSimple($"{d3.RawValue}+{d4.RawValue}", typeof(int), new IDeclaredParameter[] { d3, d4 })); var r = s1.RequiredForEquivalence(s2, new Tuple<string, string>[] { new Tuple<string, string>(d3.RawValue, d1.RawValue) }); Assert.IsTrue(r.Item1, "can do the combination"); Assert.AreEqual(1, r.Item2.Count(), "# of variables to rename"); Assert.AreEqual(d4.RawValue, r.Item2.First().Item1); }
public void TestCombineWithSameArray() { var index1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var index2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var arrayRecord = DeclarableParameter.CreateDeclarableParameterArrayExpression(typeof(int)); var stp1 = new StatementPairLoop(arrayRecord, index1, index2); var index3 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var index4 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var stp2 = new StatementPairLoop(arrayRecord, index3, index4); var statAss = new StatementAssign(index3, new ValSimple("dude", typeof(int)), null); stp2.Add(statAss); var opt = new Factories.CodeOptimizerTest(true); Assert.IsTrue(stp1.TryCombineStatement(stp2, opt), "Combine should have been ok"); Assert.AreEqual(1, stp1.Statements.Count(), "Improper number of combined sub-statements"); var s1 = stp1.Statements.First(); Assert.IsInstanceOfType(s1, typeof(StatementAssign), "Statement is not right type"); var sa = s1 as StatementAssign; Assert.AreEqual(index1.RawValue, sa.ResultVariable.RawValue, "rename of variables didn't occur correctly"); }
public void TestCombineMinimalOrdering() { // We will have two if statements to do the combination with. They basically "hide" the modification. var checkVar1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(bool)); var if1s1 = new StatementFilter(new ValSimple(checkVar1.RawValue, typeof(bool))); var if1s2 = new StatementFilter(new ValSimple(checkVar1.RawValue, typeof(bool))); var checkVar2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(bool)); var if2s1 = new StatementFilter(new ValSimple(checkVar2.RawValue, typeof(bool))); var if2s2 = new StatementFilter(new ValSimple(checkVar2.RawValue, typeof(bool))); var dummyVar = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var blockWithModified = new StatementInlineBlock(); var blockWithoutModified = new StatementInlineBlock(); blockWithModified.Add(checkVar1); blockWithModified.Add(checkVar2); blockWithModified.Add(dummyVar); blockWithoutModified.Add(checkVar1); blockWithoutModified.Add(checkVar2); blockWithoutModified.Add(dummyVar); // Not the opposite order we put them in here! blockWithModified.Add(if1s1); blockWithModified.Add(if2s1); blockWithoutModified.Add(if2s2); blockWithoutModified.Add(if1s2); if1s1.Add(new StatementAssign(dummyVar, new ValSimple("1", typeof(int)))); if2s1.Add(new StatementAssign(dummyVar, new ValSimple("2", typeof(int)))); if1s2.Add(new StatementAssign(dummyVar, new ValSimple("3", typeof(int)))); if2s2.Add(new StatementAssign(dummyVar, new ValSimple("4", typeof(int)))); // Have the modified if statement contain the modification now. var varToBeModified = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var statementModifier = new StatementAssign(varToBeModified, new ValSimple("1", typeof(int))); blockWithModified.Add(varToBeModified); if1s1.Add(statementModifier); // Next, we need to use the variable in the second if statement. Which, since it is like the first, should be pushed back up there. var finalVar = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var assignment = new StatementAssign(finalVar, varToBeModified); blockWithModified.Add(finalVar); if2s1.Add(assignment); // Combine var r = blockWithoutModified.TryCombineStatement(blockWithModified, null); Assert.IsTrue(r, "try combine result"); foreach (var s in blockWithoutModified.CodeItUp()) { System.Diagnostics.Trace.WriteLine(s); } // Make sure the checkVar guy comes after the modified statement. // To get this right (the 3 should be a 2), we need to implement a full blown statement optimizer. Assert.AreEqual(3, blockWithoutModified.Statements.Where(s => s is StatementFilter).Count(), "# of if statements."); }
private QMFuncSource[] GenerateFunction2() { var fsub = QMFuncUtils.GenerateFunction(); int[] ints = new int[10]; var h = new QMFuncHeader() { Arguments = new object[] { }, QM = new QueryModel(new MainFromClause("i", typeof(int), Expression.Constant(ints)), new SelectClause(Expression.Constant(10))) }; h.QMText = h.QM.ToString(); var f = new QMFuncSource(h); var p = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var st = new StatementAssign(p, new ValSimple(fsub.Name + "()", typeof(int))); var inlineblock = new StatementInlineBlock(); inlineblock.Add(st); inlineblock.Add(new StatementReturn(p)); f.SetCodeBody(inlineblock); return new QMFuncSource[] { fsub, f }; }
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 TestCombinePreserveOrder() { // We will have two if statements to do the combination with. They basically "hide" the modification. var checkVar1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(bool)); var if1s1 = new StatementFilter(new ValSimple(checkVar1.RawValue, typeof(bool))); var if1s2 = new StatementFilter(new ValSimple(checkVar1.RawValue, typeof(bool))); var checkVar2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(bool)); var if2s1 = new StatementFilter(new ValSimple(checkVar2.RawValue, typeof(bool))); var if2s2 = new StatementFilter(new ValSimple(checkVar2.RawValue, typeof(bool))); var blockWithModified = new StatementInlineBlock(); var blockWithoutModified = new StatementInlineBlock(); blockWithModified.Add(checkVar1); blockWithModified.Add(checkVar2); blockWithoutModified.Add(checkVar1); blockWithoutModified.Add(checkVar2); // Not the opposite order we put them in here! blockWithModified.Add(if1s1); blockWithModified.Add(if2s1); blockWithoutModified.Add(if2s2); blockWithoutModified.Add(if1s2); // Have the modified if statement contain the modification now. var varToBeModified = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var statementModifier = new StatementAssign(varToBeModified, new ValSimple("1", typeof(int))); blockWithModified.Add(varToBeModified); if1s1.Add(statementModifier); // Next, we need to use the variable in the second if statement. Which, since it is like the first, should be pushed back up there. var finalVar = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var assignment = new StatementAssign(finalVar, varToBeModified); blockWithModified.Add(finalVar); if2s1.Add(assignment); // Combine var r = blockWithoutModified.TryCombineStatement(blockWithModified, null); Assert.IsTrue(r, "try combine result"); foreach (var s in blockWithoutModified.CodeItUp()) { System.Diagnostics.Trace.WriteLine(s); } // Make sure the checkVar guy comes after the modified statement. var topLevelStatementForAssign = findStatementThatContains(blockWithoutModified, assignment); var posOfUse = findStatementIndex(blockWithoutModified, topLevelStatementForAssign); var topLevelStatementForModification = findStatementThatContains(blockWithoutModified, statementModifier); var posOfMod = findStatementIndex(blockWithoutModified, topLevelStatementForModification); Assert.IsTrue(posOfMod < posOfUse, string.Format("Modification happens after use. modification: {0} use {1}", posOfMod, posOfUse)); }
public void CombineFailsWhenNestedIsTarget() { // In this new world of moving things around, we move declaration and statements, but they aren't really connected. // So we should make sure that declaration aren't moved accidentally when they shouldn't be. // Inline block at the top var topLevel1 = new StatementInlineBlock(); var topLevel2 = new StatementInlineBlock(); // Top level guy. This is the unique filter statement. var filterUnique = new StatementFilter(new ValSimple("fUnique", typeof(bool))); topLevel1.Add(filterUnique); // Next, we will do the two common ones. var f1 = new StatementFilter(new ValSimple("f1", typeof(bool))); var f2 = new StatementFilter(new ValSimple("f1", typeof(bool))); var p1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var p2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); filterUnique.Add(p1); topLevel2.Add(p2); var a1 = new StatementAssign(p1, new ValSimple("5", typeof(int))); var a2 = new StatementAssign(p2, new ValSimple("5", typeof(int))); f1.Add(a1); f2.Add(a2); filterUnique.Add(f1); topLevel2.Add(f2); Console.WriteLine("Before optimization (target):"); topLevel1.DumpCodeToConsole(); Console.WriteLine("Before optimization (what is being merged):"); topLevel2.DumpCodeToConsole(); Assert.IsFalse(f1.TryCombineStatement(f2, null), "Two of the same if statements, and the combine should have worked"); Console.WriteLine("After optimization (target):"); topLevel1.DumpCodeToConsole(); Console.WriteLine("After optimization (merge):"); topLevel2.DumpCodeToConsole(); }
public void AssignEquivalentDiffFunc() { var p1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var d1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var s1 = new StatementAssign(p1, new ValSimple($"{d1.RawValue}", typeof(int), new IDeclaredParameter[] { d1 })); var s2 = new StatementAssign(p1, new ValSimple($"sin({d1.RawValue})", typeof(int), new IDeclaredParameter[] { d1 })); var r = s1.RequiredForEquivalence(s2); Assert.IsFalse(r.Item1, "should not be able to do the combination"); }
public void AssignEquivalentTwoDifferentDependents() { // Replacing two dependents gets to be more than we can do becasue of ordering and the roll they might // be playing. var p1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var d1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var d2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var d3 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var d4 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var s1 = new StatementAssign(p1, new ValSimple($"{d1.RawValue}+{d2.RawValue}", typeof(int), new IDeclaredParameter[] { d1, d2 })); var s2 = new StatementAssign(p1, new ValSimple($"{d3.RawValue}+{d4.RawValue}", typeof(int), new IDeclaredParameter[] { d3, d4 })); var r = s1.RequiredForEquivalence(s2); Assert.IsTrue(r.Item1, "can do the combination"); }
public void DontLiftThroughTwoForStatements() { var gc = new GeneratedCode(); var counter = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); counter.InitialValue = new ValSimple("0", typeof(int)); gc.Add(counter); // The two for loops var fc1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var for1 = new StatementForLoop(fc1, new ValSimple("5", typeof(int))); gc.Add(for1); var innerCounter = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); innerCounter.InitialValue = new ValSimple("0", typeof(int)); gc.Add(innerCounter); var fc2 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var for2 = new StatementForLoop(fc2, new ValSimple("5", typeof(int))); gc.Add(for2); // Now, calculation based only on fc1 var a1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var ass1 = new StatementAssign(a1, new ValSimple($"{fc1}*2", typeof(int), new IDeclaredParameter[] { fc1 })); gc.Add(ass1); var agg1 = new StatementAggregate(innerCounter, new ValSimple($"{innerCounter.RawValue}+{a1.RawValue}", typeof(int), new IDeclaredParameter[] { innerCounter, a1 })); gc.Add(agg1); // and the outer sum. gc.Pop(); var agg2 = new StatementAggregate(counter, new ValSimple($"{counter.RawValue}+{innerCounter.RawValue}", typeof(int), new IDeclaredParameter[] { counter, innerCounter })); gc.Add(agg2); // Great! Console.WriteLine("Unoptimized"); gc.DumpCodeToConsole(); Console.WriteLine(""); Console.WriteLine(""); Console.WriteLine(""); StatementLifter.Optimize(gc); Console.WriteLine("Optimized"); Console.WriteLine(""); gc.DumpCodeToConsole(); // Make sure the inner aggregate got lifted out properly. Assert.AreEqual(1, for2.Statements.Count(), "# of statements in the inner for loop"); }
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 AssignEquivalentSame() { var p1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var d1 = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var s1 = new StatementAssign(p1, new ValSimple($"{d1.RawValue}", typeof(int), new IDeclaredParameter[] { d1 })); var s2 = new StatementAssign(p1, new ValSimple($"{d1.RawValue}", typeof(int), new IDeclaredParameter[] { d1 })); var r = s1.RequiredForEquivalence(s2); Assert.IsTrue(r.Item1, "can do the combination"); Assert.AreEqual(0, r.Item2.Count(), "# of variables to rename"); }
public void DependentAndResultVariablesWithDecl() { var counter = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); var s = new StatementForLoop(counter, new ValSimple("5", typeof(int))); var result = DeclarableParameter.CreateDeclarableParameterExpression(typeof(int)); s.Add(result); var assign = new StatementAssign(result, new ValSimple($"{result.RawValue}+{counter.RawValue}", typeof(int), new IDeclaredParameter[] { counter, result })); s.Add(assign); Assert.AreEqual(0, s.DependentVariables.Count(), "# of dependent variables"); Assert.AreEqual(0, s.ResultVariables.Count(), "# of result variables"); }