示例#1
0
        public void CopiesWhereIntermediateIsOverwritten()
        {
            var source = @"
var x = 1;
var y = x;
y = 2;
var z = y;";

            var cfg      = CreateControlFlowGraph(source);
            var analysis = CopyPropagationAnalysis.Analyze(cfg);

            var assignmentX  = _GetNodeWithSyntax(cfg, "Assignment: x = 1");
            var assignmentY1 = _GetNodeWithSyntax(cfg, "Assignment: y = x");
            var assignmentY2 = _GetNodeWithSyntax(cfg, "Assignment: y = 2");
            var assignmentZ  = _GetNodeWithSyntax(cfg, "Assignment: z = y");

            Assert.AreEqual(0, analysis.Entry[assignmentX].Count);
            Assert.AreEqual(0, analysis.Exit[assignmentX].Count);
            Assert.AreEqual(0, analysis.Entry[assignmentY1].Count);
            Assert.AreEqual(1, analysis.Exit[assignmentY1].Count);
            Assert.AreEqual(new VariableCopy(assignmentY1, "y", "x"), analysis.Exit[assignmentY1].Single());

            Assert.AreEqual(1, analysis.Entry[assignmentY2].Count);
            Assert.IsTrue(analysis.Entry[assignmentY2].SetEquals(analysis.Exit[assignmentY1]));
            Assert.AreEqual(0, analysis.Exit[assignmentY2].Count);

            Assert.AreEqual(0, analysis.Entry[assignmentZ].Count);
            Assert.AreEqual(1, analysis.Exit[assignmentZ].Count);
            Assert.AreEqual(new VariableCopy(assignmentZ, "z", "y"), analysis.Exit[assignmentZ].Single());
        }
示例#2
0
 private CopyPropagation(Code input, ControlFlowGraph cfg, CopyPropagationAnalysis analysis,
                         IDictionary <Instruction, FlowNode> instructionNodeMapping)
 {
     _input    = input;
     _cfg      = cfg;
     _analysis = analysis;
     _instructionNodeMapping = instructionNodeMapping;
 }
示例#3
0
        /// <summary>
        /// Optimizes the given IR code by applying a copy propagation.
        /// </summary>
        /// <param name="code">The code to optimize.</param>
        /// <param name="controlFlowGraph">The control flow graph of the code.</param>
        /// <returns>A tuple of the possibly optimized code and a flag identifying if a change was applied.</returns>
        public static (Code Code, bool Changed) Optimize(Code code, ControlFlowGraph controlFlowGraph)
        {
            var analysis = CopyPropagationAnalysis.Analyze(controlFlowGraph);
            var mapping  = controlFlowGraph.Nodes
                           .ToDictionary(node => node.Instruction, node => node)
                           .ToImmutableDictionary();
            var instance = new CopyPropagation(code, controlFlowGraph, analysis, mapping);

            return(instance._Optimize(), instance._changed);
        }
示例#4
0
        public void DirectCopy()
        {
            var source   = @"var a = 1; var b = a;";
            var cfg      = CreateControlFlowGraph(source);
            var analysis = CopyPropagationAnalysis.Analyze(cfg);

            var assignmentA = _GetNodeWithSyntax(cfg, "Assignment: a = 1");
            var assignmentB = _GetNodeWithSyntax(cfg, "Assignment: b = a");

            Assert.AreEqual(0, analysis.Entry[assignmentA].Count);
            Assert.AreEqual(0, analysis.Exit[assignmentA].Count);
            Assert.AreEqual(0, analysis.Entry[assignmentB].Count);
            Assert.AreEqual(1, analysis.Exit[assignmentB].Count);
            Assert.AreEqual(new VariableCopy(assignmentB, "b", "a"), analysis.Exit[assignmentB].Single());
        }
示例#5
0
        public void NestedCopiesOnlyCopyIntermediate()
        {
            var source = @"
var x = 1;
var y = x;
var z = y;
var a = z;";

            var cfg      = CreateControlFlowGraph(source);
            var analysis = CopyPropagationAnalysis.Analyze(cfg);

            var assignmentX = _GetNodeWithSyntax(cfg, "Assignment: x = 1");
            var assignmentY = _GetNodeWithSyntax(cfg, "Assignment: y = x");
            var assignmentZ = _GetNodeWithSyntax(cfg, "Assignment: z = y");
            var assignmentA = _GetNodeWithSyntax(cfg, "Assignment: a = z");

            Assert.AreEqual(0, analysis.Entry[assignmentX].Count);
            Assert.AreEqual(0, analysis.Exit[assignmentX].Count);
            Assert.AreEqual(0, analysis.Entry[assignmentY].Count);
            Assert.AreEqual(1, analysis.Exit[assignmentY].Count);
            Assert.AreEqual(new VariableCopy(assignmentY, "y", "x"), analysis.Exit[assignmentY].Single());

            Assert.AreEqual(1, analysis.Entry[assignmentZ].Count);
            Assert.IsTrue(analysis.Entry[assignmentZ].SetEquals(analysis.Exit[assignmentY]));
            Assert.AreEqual(2, analysis.Exit[assignmentZ].Count);
            var expectedAfterZ = new HashSet <VariableCopy> {
                new VariableCopy(assignmentY, "y", "x"),
                new VariableCopy(assignmentZ, "z", "y"),
            };

            Assert.IsTrue(expectedAfterZ.SetEquals(analysis.Exit[assignmentZ]));

            Assert.AreEqual(2, analysis.Entry[assignmentA].Count);
            Assert.IsTrue(analysis.Entry[assignmentA].SetEquals(analysis.Exit[assignmentZ]));
            Assert.AreEqual(3, analysis.Exit[assignmentA].Count);
            var expectedAfterA = new HashSet <VariableCopy> {
                new VariableCopy(assignmentY, "y", "x"),
                new VariableCopy(assignmentZ, "z", "y"),
                new VariableCopy(assignmentA, "a", "z"),
            };

            Assert.IsTrue(expectedAfterA.SetEquals(analysis.Exit[assignmentA]));
        }
示例#6
0
        public void CopyAfterLoopBranch()
        {
            var source = @"
var x = 1;
for(var i = 0; i < 10; ++i) {
  x = 2;
}
var y = x;";

            var cfg      = CreateControlFlowGraph(source);
            var analysis = CopyPropagationAnalysis.Analyze(cfg);

            var assignmentX1 = _GetNodeWithSyntax(cfg, "Assignment: x = 1");
            var assignmentX2 = _GetNodeWithSyntax(cfg, "Assignment: x = 2");
            var assignmentY  = _GetNodeWithSyntax(cfg, "Assignment: y = x");

            Assert.AreEqual(0, analysis.Entry[assignmentX1].Count);
            Assert.AreEqual(0, analysis.Exit[assignmentX1].Count);
            Assert.AreEqual(0, analysis.Entry[assignmentX2].Count);
            Assert.AreEqual(0, analysis.Exit[assignmentX2].Count);
            Assert.AreEqual(0, analysis.Entry[assignmentY].Count);
            Assert.AreEqual(1, analysis.Exit[assignmentY].Count);
            Assert.AreEqual(new VariableCopy(assignmentY, "y", "x"), analysis.Exit[assignmentY].Single());
        }
示例#7
0
 public InstructionVisitor(CopyPropagationAnalysis analysis, FlowNode flowNode)
 {
     _analysis = analysis;
     _flowNode = flowNode;
 }