Ejemplo n.º 1
0
        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));
        }
Ejemplo n.º 2
0
        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));
        }
Ejemplo n.º 3
0
        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));
        }
Ejemplo n.º 4
0
        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));
        }
Ejemplo n.º 5
0
        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));
        }
Ejemplo n.º 6
0
        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));
        }
Ejemplo n.º 7
0
        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));
        }
Ejemplo n.º 8
0
        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);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Perform basic optimizations on high-level IL representation.
        /// </summary>
        public void Optimize()
        {
            bool Changed;

            do
            {
                Changed  = CopyPropagation.Do(this);
                Changed |= DeadAssignmentElimination.Do(this);
            } while (Changed);
        }
Ejemplo n.º 10
0
        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);
        }
Ejemplo n.º 11
0
        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);
        }
Ejemplo n.º 12
0
        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);
        }
Ejemplo n.º 13
0
        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);
        }
        private List <IOptimization> BlockOptimizationList()
        {
            var optimizations = new List <IOptimization>();

            if (OptimizationList[Optimizations.Alg])
            {
                var algOptimization = new AlgebraicOptimization();
                optimizations.Add(algOptimization);
            }

            if (OptimizationList[Optimizations.Decl])
            {
                var declOptimization = new DeclarationOptimization();
                optimizations.Add(declOptimization);
            }

            if (OptimizationList[Optimizations.CopyProp])
            {
                var copyPropOptimization = new CopyPropagation();
                optimizations.Add(copyPropOptimization);
            }

            if (OptimizationList[Optimizations.ConstFold])
            {
                var constFoldingOptimization = new ConstantFolding();
                optimizations.Add(constFoldingOptimization);
            }

            if (OptimizationList[Optimizations.ConstProp])
            {
                var constPropOptimization = new ConstantPropagation();
                optimizations.Add(constPropOptimization);
            }

            if (OptimizationList[Optimizations.Subexpr])
            {
                var subexpOptimization = new SubexpressionOptimization();
                optimizations.Add(subexpOptimization);
            }

            return(optimizations);
        }
Ejemplo n.º 15
0
        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));
        }
Ejemplo n.º 16
0
        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));
        }
Ejemplo n.º 17
0
        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("-----------------------------------------");
        }
        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);
        }