Пример #1
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));
        }
Пример #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));
        }
Пример #3
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));
        }
Пример #4
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));
        }
Пример #5
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));
        }
Пример #6
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));
        }
Пример #7
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));
        }
        public ControlFlowGraph CreateControlFlowGraph(string body)
        {
            var code = TestCodeFactory.CreateThreeAddressCode(body);

            Debug.WriteLine(CodeStringifier.Generate(code));
            return(ControlFlowGraphFactory.Create(code));
        }
Пример #9
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);
        }
Пример #10
0
        public void CodeWithoutCommonSubexpressionsDueToDifferentMethods()
        {
            var source    = "var x = Method1(1); var y = Method2(1); var z = y * 1;";
            var code      = TestCodeFactory.CreateThreeAddressCode(source);
            var cfg       = ControlFlowGraphFactory.Create(code);
            var optimized = CommonSubexpressionElimination.Optimize(code, cfg);

            Assert.AreEqual(code, optimized.Code);
            Assert.IsFalse(optimized.Changed);
        }
Пример #11
0
        public void CommonSubexpressionsWithMultipleInvocationsOfTheSameMethodWithDistinctArguments()
        {
            var source    = @"var result = Method(x) + Method(y);";
            var code      = TestCodeFactory.CreateThreeAddressCode(source);
            var cfg       = ControlFlowGraphFactory.Create(code);
            var optimized = CommonSubexpressionElimination.Optimize(code, cfg);

            Assert.AreEqual(code, optimized.Code);
            Assert.IsFalse(optimized.Changed);
        }
Пример #12
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);
        }
Пример #13
0
        public void CodeWithSameInvocationsButIntermediateValueChange()
        {
            var source    = @"
var x = 5;
var a = Method(x);
x = 2;
var b = Method(x);";
            var code      = TestCodeFactory.CreateThreeAddressCode(source);
            var cfg       = ControlFlowGraphFactory.Create(code);
            var optimized = CommonSubexpressionElimination.Optimize(code, cfg);

            Assert.AreEqual(code, optimized.Code);
            Assert.IsFalse(optimized.Changed);
        }
Пример #14
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);
        }
Пример #15
0
        public void SelfAssignmentNegatesOptimization()
        {
            var source    = @"
var x = 5;
var y = 3;

x = x + y;
var a = x + y;";
            var code      = TestCodeFactory.CreateThreeAddressCode(source);
            var cfg       = ControlFlowGraphFactory.Create(code);
            var optimized = CommonSubexpressionElimination.Optimize(code, cfg);

            Assert.AreEqual(code, optimized.Code);
            Assert.IsFalse(optimized.Changed);
        }
Пример #16
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);
        }
Пример #17
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);
        }
Пример #18
0
        public void CodeWithSameInvocationsButInLoop()
        {
            var source    = @"
var x = 5;
var y = 3;

var a = Method(x);
for(var i = 0; i < 10; ++i) {
  x = Method(x);
}";
            var code      = TestCodeFactory.CreateThreeAddressCode(source);
            var cfg       = ControlFlowGraphFactory.Create(code);
            var optimized = CommonSubexpressionElimination.Optimize(code, cfg);

            Assert.AreEqual(code, optimized.Code);
            Assert.IsFalse(optimized.Changed);
        }
Пример #19
0
        public void CodeWithSameExpressionsButBranchedValueChange()
        {
            var source    = @"
var x = 5;
var y = 3;

var a = y + x;
if(x > y) {
  x = 2;
}
var b = y + x;";
            var code      = TestCodeFactory.CreateThreeAddressCode(source);
            var cfg       = ControlFlowGraphFactory.Create(code);
            var optimized = CommonSubexpressionElimination.Optimize(code, cfg);

            Assert.AreEqual(code, optimized.Code);
            Assert.IsFalse(optimized.Changed);
        }
Пример #20
0
        public void NestedConditionalExpressions()
        {
            var source   = @"var x = a > 0 ? 1 : (a < 0 ? 1 : 0);";
            var cfg      = ControlFlowGraphFactory.Create(TestCodeFactory.CreateThreeAddressCode(source));
            var expected = @"
digraph cfg {
  ""0"" [ label = ""<End>"" ];
  ""1"" [ label = ""<Start>"" ];
  ""2"" [ label = ""Assignment: $temp_0 = $temp_1"" ];
  ""3"" [ label = ""Assignment: $temp_0 = 1"" ];
  ""4"" [ label = ""Assignment: $temp_1 = 0"" ];
  ""5"" [ label = ""Assignment: $temp_1 = 1"" ];
  ""6"" [ label = ""Assignment: x = $temp_0"" ];
  ""7"" [ label = ""ConditionalJump: a < 0"" ];
  ""8"" [ label = ""ConditionalJump: a > 0"" ];
  ""9"" [ label = ""Declaration: $temp_0"" ];
  ""10"" [ label = ""Declaration: $temp_1"" ];
  ""11"" [ label = ""Declaration: x"" ];
  ""12"" [ label = ""Label"" ];
  ""13"" [ label = ""Label"" ];
  ""14"" [ label = ""Label"" ];
  ""15"" [ label = ""Label"" ];
  ""1"" -> ""11"" [ label = """" ];
  ""2"" -> ""15"" [ label = """" ];
  ""3"" -> ""15"" [ label = """" ];
  ""4"" -> ""14"" [ label = """" ];
  ""5"" -> ""14"" [ label = """" ];
  ""6"" -> ""0"" [ label = """" ];
  ""7"" -> ""4"" [ label = """" ];
  ""7"" -> ""13"" [ label = """" ];
  ""8"" -> ""10"" [ label = """" ];
  ""8"" -> ""12"" [ label = """" ];
  ""9"" -> ""8"" [ label = """" ];
  ""10"" -> ""7"" [ label = """" ];
  ""11"" -> ""9"" [ label = """" ];
  ""14"" -> ""2"" [ label = """" ];
  ""12"" -> ""3"" [ label = """" ];
  ""13"" -> ""5"" [ label = """" ];
  ""15"" -> ""6"" [ label = """" ];
}";

            Assert.AreEqual(expected.Trim(), cfg.ToDot());
        }
Пример #21
0
        public void CommonSubexpressionsInSingleMethodInvocation()
        {
            var source    = @"Method(x + 1, x + 1);";
            var code      = TestCodeFactory.CreateThreeAddressCode(source);
            var cfg       = ControlFlowGraphFactory.Create(code);
            var optimized = CommonSubexpressionElimination.Optimize(code, cfg);

            Assert.AreNotEqual(code, optimized.Code);
            Assert.IsTrue(optimized.Changed);

            var expected = @"
DECL $temp_0
$temp_0 = x + 1
DECL $temp_1
$temp_1 = $temp_0
INVOKE Method($temp_0, $temp_1)";

            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(optimized.Code));
        }
Пример #22
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));
        }
Пример #23
0
        public void CommonSubexpressionsWithMultipleInvocationsOfTheSameMethodWithTheSameArguments()
        {
            var source    = @"var result = Method(x) + Method(x);";
            var code      = TestCodeFactory.CreateThreeAddressCode(source);
            var cfg       = ControlFlowGraphFactory.Create(code);
            var optimized = CommonSubexpressionElimination.Optimize(code, cfg);

            Assert.AreNotEqual(code, optimized.Code);
            Assert.IsTrue(optimized.Changed);

            var expected = @"
DECL result
DECL $temp_0
$temp_0 = Method(x)
DECL $temp_1
$temp_1 = $temp_0
result = $temp_0 + $temp_1";

            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(optimized.Code));
        }
Пример #24
0
        public void CodeWithSingleCommonInvocation()
        {
            var source    = "var x = 3; var y = Method(x); var z = Method(x);";
            var code      = TestCodeFactory.CreateThreeAddressCode(source);
            var cfg       = ControlFlowGraphFactory.Create(code);
            var optimized = CommonSubexpressionElimination.Optimize(code, cfg);

            Assert.AreNotEqual(code, optimized.Code);
            Assert.IsTrue(optimized.Changed);

            var expected = @"
DECL x
x = 3
DECL y
y = Method(x)
DECL z
z = y";

            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(optimized.Code));
        }
Пример #25
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));
        }
Пример #26
0
        public void CodeWithCommonInvocationArgumentExpressions()
        {
            var source    = @"
var a = Method[x + 1];
Method[x + 1] = 4;";
            var code      = TestCodeFactory.CreateThreeAddressCode(source);
            var cfg       = ControlFlowGraphFactory.Create(code);
            var optimized = CommonSubexpressionElimination.Optimize(code, cfg);

            Assert.AreNotEqual(code, optimized.Code);
            Assert.IsTrue(optimized.Changed);

            var expected = @"
DECL a
DECL $temp_0
$temp_0 = x + 1
a = Method[$temp_0]
DECL $temp_1
$temp_1 = $temp_0
Method[$temp_1] = 4";

            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(optimized.Code));
        }
Пример #27
0
        public void CommonSubexpressionsInMultipleMethodInvocations()
        {
            var source    = @"var result = Method1(x + 1) + Method2(x + 1);";
            var code      = TestCodeFactory.CreateThreeAddressCode(source);
            var cfg       = ControlFlowGraphFactory.Create(code);
            var optimized = CommonSubexpressionElimination.Optimize(code, cfg);

            Assert.AreNotEqual(code, optimized.Code);
            Assert.IsTrue(optimized.Changed);

            var expected = @"
DECL result
DECL $temp_0
$temp_0 = x + 1
DECL $temp_1
$temp_1 = Method1($temp_0)
DECL $temp_2
$temp_2 = $temp_0
DECL $temp_3
$temp_3 = Method2($temp_2)
result = $temp_1 + $temp_3";

            Assert.AreEqual(expected.Trim(), CodeStringifier.Generate(optimized.Code));
        }
Пример #28
0
 private Code _CreateCode(string body)
 {
     return(TestCodeFactory.CreateThreeAddressCode(body));
 }