public void CodeWithCodeWithCopyUsageDoesNotPropagateNestedCopies() { var source = @" var x = 0; var y = x; var z = y; var a = z; var b = a; var c = b;"; var code = TestCodeFactory.CreateThreeAddressCode(source); var cfg = ControlFlowGraphFactory.Create(code); var optimized = CopyPropagation.Optimize(code, cfg); Assert.AreNotEqual(code, optimized.Code); Assert.IsTrue(optimized.Changed); var expected = @" DECL x x = 0 DECL y y = x DECL z z = x DECL a a = y DECL b b = z DECL c c = a"; Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(optimized.Code)); }
public void CopyUsageInNestedBinaryExpressions() { var source = @" var x = 0; var y = x; var a = 4; var b = a; var c = x + y * b - y;"; var code = TestCodeFactory.CreateThreeAddressCode(source); var cfg = ControlFlowGraphFactory.Create(code); var optimized = CopyPropagation.Optimize(code, cfg); Assert.AreNotEqual(code, optimized.Code); Assert.IsTrue(optimized.Changed); var expected = @" DECL x x = 0 DECL y y = x DECL a a = 4 DECL b b = a DECL c DECL $temp_0 $temp_0 = x * a DECL $temp_1 $temp_1 = x + $temp_0 c = $temp_1 - x"; Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(optimized.Code)); }
public void CopyUsageInNestedMethodInvocations() { var source = @" var x = 0; var y = x; Outer(x, Inner1(Inner2(y)));"; var code = TestCodeFactory.CreateThreeAddressCode(source); var cfg = ControlFlowGraphFactory.Create(code); var optimized = CopyPropagation.Optimize(code, cfg); Assert.AreNotEqual(code, optimized.Code); Assert.IsTrue(optimized.Changed); var expected = @" DECL x x = 0 DECL y y = x DECL $temp_0 $temp_0 = Inner2(x) DECL $temp_1 $temp_1 = Inner1($temp_0) INVOKE Outer(x, $temp_1)"; Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(optimized.Code)); }
public void CopyUsageInArrayAccessor() { var source = @" var x = 0; var y = x; var z = 5 + array[y]"; var code = TestCodeFactory.CreateThreeAddressCode(source); var cfg = ControlFlowGraphFactory.Create(code); var optimized = CopyPropagation.Optimize(code, cfg); Assert.AreNotEqual(code, optimized.Code); Assert.IsTrue(optimized.Changed); var expected = @" DECL x x = 0 DECL y y = x DECL z DECL $temp_0 $temp_0 = array[x] z = 5 + $temp_0"; Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(optimized.Code)); }
public void CopyUsageInCondition() { var source = @" var x = 0; var y = x; if(y == x) { }"; var code = TestCodeFactory.CreateThreeAddressCode(source); var cfg = ControlFlowGraphFactory.Create(code); var optimized = CopyPropagation.Optimize(code, cfg); Assert.AreNotEqual(code, optimized.Code); Assert.IsTrue(optimized.Changed); var expected = @" DECL x x = 0 DECL y y = x IF x == x JUMP #0 JUMP #1 LABEL #0 LABEL #1"; Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(optimized.Code)); }
public void CodeWithSameVariableAndDoubleIntermediateOverwritingDoesNotAffectSucceedingCopies() { var source = @" var x = 0; var y = x; var z = y; x = 5; var a = y; var b = z;"; var code = TestCodeFactory.CreateThreeAddressCode(source); var cfg = ControlFlowGraphFactory.Create(code); var optimized = CopyPropagation.Optimize(code, cfg); Assert.AreNotEqual(code, optimized.Code); Assert.IsTrue(optimized.Changed); var expected = @" DECL x x = 0 DECL y y = x DECL z z = x x = 5 DECL a a = y DECL b b = y"; Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(optimized.Code)); }
public void CodeWithUsageAndCopyInBranch() { var source = @" var x = 0; var y = 5; if(x > 0) { y = x; var z = y; }"; var code = TestCodeFactory.CreateThreeAddressCode(source); var cfg = ControlFlowGraphFactory.Create(code); var optimized = CopyPropagation.Optimize(code, cfg); Assert.AreNotEqual(code, optimized.Code); Assert.IsTrue(optimized.Changed); var expected = @" DECL x x = 0 DECL y y = 5 IF x > 0 JUMP #0 JUMP #1 LABEL #0 y = x DECL z z = x LABEL #1"; Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(optimized.Code)); }
public void EmptyCode() { var source = ""; var code = TestCodeFactory.CreateThreeAddressCode(source); var cfg = ControlFlowGraphFactory.Create(code); var optimized = CopyPropagation.Optimize(code, cfg); Assert.AreEqual(code, optimized.Code); Assert.IsFalse(optimized.Changed); }
public void CodeWithoutCopies() { var source = "var x = 0; var y = 2; var z = x + y;"; var code = TestCodeFactory.CreateThreeAddressCode(source); var cfg = ControlFlowGraphFactory.Create(code); var optimized = CopyPropagation.Optimize(code, cfg); Assert.AreEqual(code, optimized.Code); Assert.IsFalse(optimized.Changed); }
public void CodeWithSameVariableButIntermediateOverwriting() { var source = @" var x = 0; var y = x; x = 5; var z = y;"; var code = TestCodeFactory.CreateThreeAddressCode(source); var cfg = ControlFlowGraphFactory.Create(code); var optimized = CopyPropagation.Optimize(code, cfg); Assert.AreEqual(code, optimized.Code); Assert.IsFalse(optimized.Changed); }
public void CodeWithInLoopCopy() { var source = @" var x = 0; var y = x + 1; for(var i = 0; i < 10; ++i) { x = x + 1; }"; var code = TestCodeFactory.CreateThreeAddressCode(source); var cfg = ControlFlowGraphFactory.Create(code); var optimized = CopyPropagation.Optimize(code, cfg); Assert.AreEqual(code, optimized.Code); Assert.IsFalse(optimized.Changed); }
public void CodeWithBranchOnlyCopy() { var source = @" var x = 0; var y = 2; if(x > 0) { y = x; } var z = y;"; var code = TestCodeFactory.CreateThreeAddressCode(source); var cfg = ControlFlowGraphFactory.Create(code); var optimized = CopyPropagation.Optimize(code, cfg); Assert.AreEqual(code, optimized.Code); Assert.IsFalse(optimized.Changed); }
public void CodeWithCodeWithSingleCopyUsage() { var source = "var x = 0; var y = x; var z = y;"; var code = TestCodeFactory.CreateThreeAddressCode(source); var cfg = ControlFlowGraphFactory.Create(code); var optimized = CopyPropagation.Optimize(code, cfg); Assert.AreNotEqual(code, optimized.Code); Assert.IsTrue(optimized.Changed); var expected = @" DECL x x = 0 DECL y y = x DECL z z = x"; Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(optimized.Code)); }
public void CopyUsageInMethodInvocation() { var source = @" var x = 0; var y = x; Method(x, y);"; var code = TestCodeFactory.CreateThreeAddressCode(source); var cfg = ControlFlowGraphFactory.Create(code); var optimized = CopyPropagation.Optimize(code, cfg); Assert.AreNotEqual(code, optimized.Code); Assert.IsTrue(optimized.Changed); var expected = @" DECL x x = 0 DECL y y = x INVOKE Method(x, x)"; Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(optimized.Code)); }
public void Test1() { var taCodeConstProp = new TACode(); var assgn1 = new Assign() { Left = null, Operation = OpCode.Copy, Right = new IntConst(10), Result = new Var() }; var assgn2 = new Assign() { Left = new Var(), Operation = OpCode.Minus, Right = assgn1.Result, Result = new Var() }; var assgn3 = new Assign() { Left = assgn2.Result, Operation = OpCode.Plus, Right = new IntConst(1), Result = new Var() }; var assgn4 = new Assign() { Left = assgn3.Result, Operation = OpCode.Mul, Right = assgn1.Result, Result = new Var() }; var assgn5 = new Assign() { Left = new IntConst(30), Operation = OpCode.Minus, Right = new IntConst(20), Result = assgn1.Result }; var assgn6 = new Assign() { Left = assgn2.Result, Operation = OpCode.Plus, Right = assgn5.Result, Result = new Var() }; taCodeConstProp.AddNode(assgn1); taCodeConstProp.AddNode(assgn2); taCodeConstProp.AddNode(assgn3); taCodeConstProp.AddNode(assgn4); taCodeConstProp.AddNode(assgn5); taCodeConstProp.AddNode(assgn6); var optConstProp = new CopyPropagation(); optConstProp.Optimize(taCodeConstProp.CodeList.ToList(), out var applCopProp); /* * a = 10 * c = b - a -----> c = b - 10 * d = c + 1 * e = d * a -----> e = d * 10 * a = 30 - 20 * k = c + a -----> k = c + a */ Assert.AreEqual(assgn2.Right, assgn1.Result); Assert.AreEqual(assgn4.Right, assgn1.Result); Assert.AreNotSame(assgn6.Right, assgn1.Result); Assert.True(true); }
private static void TaCodeTest() { var taCode = new TACode(); var ass1 = new Assign { Left = new IntConst(3), //Left = new IntConst(5), Operation = OpCode.Minus, Right = new IntConst(5), Result = new Var() }; var ass2 = new Assign { Left = new IntConst(10), Operation = OpCode.Plus, Right = new IntConst(2), Result = new Var() }; var ass3 = new Assign { Operation = OpCode.Minus, Right = new IntConst(1), Result = new Var() }; var ifgt1 = new IfGoto { Condition = new IntConst(1), TargetLabel = ass3.Label }; ass3.IsLabeled = true; //На этот оперетор мы переходим по условию var ass4 = new Assign { Left = ass3.Result, Operation = OpCode.Plus, Right = new IntConst(1999), Result = new Var() }; var ifgt2 = new IfGoto { Condition = new IntConst(2), TargetLabel = ass2.Label }; ass2.IsLabeled = true; //На этот оперетор мы переходим по условию var ass5 = new Assign { Left = new IntConst(7), Operation = OpCode.Mul, Right = new IntConst(4), Result = new Var() }; var ass6 = new Assign { Left = new IntConst(100), Operation = OpCode.Div, Right = new IntConst(25), Result = new Var() }; taCode.AddNode(ass1); taCode.AddNode(ass2); taCode.AddNode(ass3); taCode.AddNode(ifgt1); taCode.AddNode(ass4); taCode.AddNode(ifgt2); taCode.AddNode(ass5); taCode.AddNode(ass6); var algOpt = new AlgebraicOptimization(); algOpt.Optimize(taCode.CodeList.ToList(), out var applied); Console.WriteLine($"TA Code\n: {taCode}"); var bBlocks = taCode.CreateBasicBlockList(); foreach (var bbl in bBlocks) { Console.WriteLine($"Block[{bbl.BlockId}]:"); var bblCodeStr = bbl.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine); Console.WriteLine($"{bblCodeStr}\n"); } Console.WriteLine($"Algebraic Optimization was{(applied ? "" : "n't")} applied"); Console.WriteLine("========================CFG test========================"); var cfg = new ControlFlowGraph(taCode); foreach (var cfgn in cfg.CFGNodes) { Console.WriteLine($"Block[{cfgn.BlockId}]"); var bblCodeStr = cfgn.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine); Console.WriteLine($"{bblCodeStr}\n"); Console.WriteLine("Children:\n"); foreach (var ch in cfgn.Children) { Console.WriteLine($"Block[{ch.BlockId}]"); var bblCodeCh = ch.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine); Console.WriteLine($"{bblCodeCh}\n"); } Console.WriteLine("Parents:\n"); foreach (var ch in cfgn.Parents) { Console.WriteLine($"Block[{ch.BlockId}]"); var bblCodeCh = ch.CodeList.Aggregate("", (s, node) => s + node.ToString() + Environment.NewLine); Console.WriteLine($"{bblCodeCh}\n"); } Console.WriteLine("-----------------------------------------"); } //Copy Propagation Test var taCodeCopyProp = new TACode(); var assgn1 = new Assign() { Left = null, Operation = OpCode.Copy, Right = new Var(), Result = new Var() }; var assgn2 = new Assign() { Left = assgn1.Right, Operation = OpCode.Minus, Right = assgn1.Result, Result = new Var() }; var assgn3 = new Assign() { Left = assgn2.Result, Operation = OpCode.Plus, Right = new IntConst(1), Result = new Var() }; var assgn4 = new Assign() { Left = assgn3.Result, Operation = OpCode.Mul, Right = assgn1.Result, Result = new Var() }; var assgn5 = new Assign() { Left = new IntConst(30), Operation = OpCode.Minus, Right = new IntConst(20), Result = assgn1.Result }; var assgn6 = new Assign() { Left = assgn2.Result, Operation = OpCode.Plus, Right = assgn5.Result, Result = new Var() }; taCodeCopyProp.AddNode(assgn1); taCodeCopyProp.AddNode(assgn2); taCodeCopyProp.AddNode(assgn3); taCodeCopyProp.AddNode(assgn4); taCodeCopyProp.AddNode(assgn5); taCodeCopyProp.AddNode(assgn6); /* * a = b * c = b - a -----> c = b - b * d = c + 1 * e = d * a -----> e = d * b * a = 30 - 20 * k = c + a -----> k = c + a */ Console.WriteLine($"Testing Copy Propagation Optimisation.\n Three Adress Code:\n {taCodeCopyProp}"); var optCopyProp = new CopyPropagation(); optCopyProp.Optimize(taCodeCopyProp.CodeList.ToList(), out var applCopProp); Console.WriteLine($"Optimisation Copy Propagation was{(applCopProp ? "" : "n't")} applied"); Console.WriteLine($"Three Adress Code Code\n: {taCodeCopyProp}"); Console.WriteLine("-----------------------------------------"); //Constant Folding Test var taCodeConstantFolding = new TACode(); var assign1 = new Assign() { Left = null, Operation = OpCode.Copy, Right = new Var(), Result = new Var() }; var assign2 = new Assign() { Left = new IntConst(20), Operation = OpCode.Mul, Right = new IntConst(3), Result = new Var() }; var assign3 = new Assign() { Left = new IntConst(10), Operation = OpCode.Plus, Right = new IntConst(1), Result = new Var() }; var assign4 = new Assign() { Left = new IntConst(100), Operation = OpCode.Div, Right = new IntConst(50), Result = new Var() }; var assign5 = new Assign() { Left = new IntConst(30), Operation = OpCode.Minus, Right = new IntConst(20), Result = assign1.Result }; var assign6 = new Assign() { Left = assign2.Result, Operation = OpCode.Plus, Right = assign5.Result, Result = new Var() }; taCodeConstantFolding.AddNode(assign1); taCodeConstantFolding.AddNode(assign2); taCodeConstantFolding.AddNode(assign3); taCodeConstantFolding.AddNode(assign4); taCodeConstantFolding.AddNode(assign5); taCodeConstantFolding.AddNode(assign6); /* * a = b * c = 20 * 3 -----> c = 60 * d = 10 + 1 -----> d = 11 * e = 100 / 50 -----> e = 2 * a = 30 - 20 -----> a = 10 * k = c + a */ Console.WriteLine($"Testing Constant Folding Optimisation.\n Three Adress Code:\n {taCodeConstantFolding}"); var optConstFold = new ConstantFolding(); optConstFold.Optimize(taCodeConstantFolding.CodeList.ToList(), out var applConstFold); Console.WriteLine($"Optimisation Constant Folding was{(applConstFold ? "" : "n't")} applied"); Console.WriteLine($"Three Adress Code Code\n: {taCodeConstantFolding}"); Console.WriteLine("-----------------------------------------"); //All Optimizations Together Test var taCodeAllOptimizations = new TACode(); var a1 = new Assign() { Left = null, Operation = OpCode.Copy, Right = new Var(), Result = new Var() }; var a2 = new Assign() { Left = a1.Right, Operation = OpCode.Minus, Right = a1.Result, Result = new Var() }; var a3 = new Assign() { Left = null, Operation = OpCode.Copy, Right = new IntConst(20), Result = new Var() }; var a4 = new Assign() { Left = new IntConst(20), Operation = OpCode.Mul, Right = new IntConst(3), Result = new Var() }; var a5 = new Assign() { Left = new IntConst(10), Operation = OpCode.Plus, Right = a3.Result, Result = new Var() }; taCodeAllOptimizations.AddNode(a1); taCodeAllOptimizations.AddNode(a2); taCodeAllOptimizations.AddNode(a3); taCodeAllOptimizations.AddNode(a4); taCodeAllOptimizations.AddNode(a5); /* * a = b * c = b - a -----> c = 0 * n = 20 * c = 20 * 3 -----> c = 60 * d = 10 + n -----> d = 30 */ Console.WriteLine($"Testing All Optimizations Together.\n Three Adress Code:\n {taCodeAllOptimizations}"); var allOptimizations = new AllOptimizations(); allOptimizations.ApplyAllOptimizations(taCodeAllOptimizations); Console.WriteLine($"Three Adress Code Code\n: {taCodeAllOptimizations}"); Console.WriteLine("-----------------------------------------"); }