コード例 #1
0
        public void NotEliminationBlocksTest()
        {
            var TAC = GenTAC(@"
var a, b, c;

goto 1;
1: b = 3;
c = 5;
goto 2;
2: b = 53;
c = b == 53;
");
            var cfg = new ControlFlowGraph(BasicBlockLeader.DivideLeaderToLeader(TAC));

            List <BasicBlock> actual = cfg.GetCurrentBasicBlocks().ToList();

            var expected = new List <BasicBlock>()
            {
                new BasicBlock(new List <Instruction>()
                {
                    new Instruction("", "goto", "1", "", "")
                }),
                new BasicBlock(new List <Instruction>()
                {
                    new Instruction("1", "assign", "3", "", "b"), new Instruction("", "assign", "5", "", "c"), new Instruction("", "goto", "2", "", "")
                }),
                new BasicBlock(new List <Instruction>()
                {
                    new Instruction("2", "assign", "53", "", "b"), new Instruction("", "EQUAL", "b", "53", "#t1"), new Instruction("", "assign", "#t1", "", "c")
                }),
            };


            AssertSet(expected, actual.Skip(1).Take(actual.Count - 2).ToList());
        }
コード例 #2
0
        public void TransfNotDistr()
        {
            var TAC    = GenTAC(@"
var a,b,c;
if c > 5
{
    a = 2;
    b = 3;
}
else
{
    a = 3;
    b = 2;
}
c = a + b;
");
            var blocks = BasicBlockLeader.DivideLeaderToLeader(TAC);

            Assert.AreEqual(4, blocks.Count);
            var cfg   = new ControlFlowGraph(blocks);
            var InOut = new ConstPropagation().ExecuteNonGeneric(cfg);

            Assert.AreEqual(InOut.OUT[blocks[3]]["a"].Type, LatticeTypeData.NAC);
            Assert.AreEqual(InOut.OUT[blocks[3]]["b"].Type, LatticeTypeData.NAC);
            Assert.AreEqual(InOut.OUT[blocks[3]]["c"].Type, LatticeTypeData.NAC);
        }
コード例 #3
0
        public void ForReverse()
        {
            var TAC    = GenTAC(@"
var a, b, x, c, d;
for x=1,2
{
    a = b;
    b = c;
    c = d;
    d = 5;
}
");
            var blocks = BasicBlockLeader.DivideLeaderToLeader(TAC);
            var cfg    = new ControlFlowGraph(blocks);
            var InOut  = new ConstPropagation().ExecuteNonGeneric(cfg);

            Assert.AreEqual(LatticeTypeData.CONST, InOut.OUT[blocks[3]]["a"].Type);
            Assert.AreEqual(LatticeTypeData.CONST, InOut.OUT[blocks[3]]["b"].Type);
            Assert.AreEqual(LatticeTypeData.CONST, InOut.OUT[blocks[3]]["c"].Type);
            Assert.AreEqual(LatticeTypeData.CONST, InOut.OUT[blocks[3]]["d"].Type);

            Assert.AreEqual("5", InOut.OUT[blocks[3]]["a"].ConstValue);
            Assert.AreEqual("5", InOut.OUT[blocks[3]]["b"].ConstValue);
            Assert.AreEqual("5", InOut.OUT[blocks[3]]["c"].ConstValue);
            Assert.AreEqual("5", InOut.OUT[blocks[3]]["d"].ConstValue);
        }
コード例 #4
0
        public void EliminationdMultyBlocksTest3()
        {
            var TAC = GenTAC(@"
var a, b, c;
2: goto 1;
1: goto 2;
goto 3;
3: a = 5;

");
            var cfg = new ControlFlowGraph(BasicBlockLeader.DivideLeaderToLeader(TAC));

            var actual = cfg.GetCurrentBasicBlocks().ToList();

            var expected = new List <BasicBlock>()
            {
                new BasicBlock(new List <Instruction>()
                {
                    TAC[0]
                }),
                new BasicBlock(new List <Instruction>()
                {
                    TAC[1]
                }),
            };


            AssertSet(expected, actual.Skip(1).Take(actual.Count - 2).ToList());
        }
コード例 #5
0
        internal static (string str, ControlFlowGraph cfg) BuildCFG(IReadOnlyList <Instruction> instructions)
        {
            var divResult = BasicBlockLeader.DivideLeaderToLeader(instructions);
            var cfg       = new ControlFlowGraph(divResult);

            var str = new StringBuilder();

            foreach (var block in cfg.GetCurrentBasicBlocks())
            {
                str.AppendLine($"{cfg.VertexOf(block)} --------");
                foreach (var inst in block.GetInstructions())
                {
                    str.AppendLine(inst.ToString());
                }
                str.AppendLine($"----------");

                var children = cfg.GetChildrenBasicBlocks(cfg.VertexOf(block));

                var childrenStr = string.Join(" | ", children.Select(v => v.vertex));
                str.AppendLine($" children: {childrenStr}");

                var parents    = cfg.GetParentsBasicBlocks(cfg.VertexOf(block));
                var parentsStr = string.Join(" | ", parents.Select(v => v.vertex));
                str.AppendLine($" parents: {parentsStr}\r\n");
            }

            return(str.ToString(), cfg);
        }
コード例 #6
0
        public void DivBBGotoTest()
        {
            var TAC = GenTAC(@"
goto 1;
1: goto 1;
2: goto 1;
");

            var expected = new List <BasicBlock>()
            {
                new BasicBlock(new List <Instruction>()
                {
                    new Instruction("", "goto", "1", "", "")
                }),
                new BasicBlock(new List <Instruction>()
                {
                    new Instruction("1", "goto", "1", "", "")
                }),
                new BasicBlock(new List <Instruction>()
                {
                    new Instruction("2", "goto", "1", "", "")
                }),
            };
            var actual = BasicBlockLeader.DivideLeaderToLeader(TAC);

            AssertSet(expected, actual);
        }
コード例 #7
0
        private List <(List <OneExpression>, List <OneExpression>)> GetActualInOutData(List <Instruction> TAC)
        {
            cfg = new ControlFlowGraph(BasicBlockLeader.DivideLeaderToLeader(TAC));
            availableExpressions    = new AvailableExpressions();
            resAvailableExpressions = availableExpressions.Execute(cfg);
            In  = new List <OneExpression>();
            Out = new List <OneExpression>();
            var actual = new List <(List <OneExpression>, List <OneExpression>)>();

            foreach (var block in resAvailableExpressions)
            {
                foreach (var expr in block.Value.In)
                {
                    In.Add(expr);
                }
                foreach (var expr in block.Value.Out)
                {
                    Out.Add(expr);
                }
                actual.Add((new List <OneExpression>(In), new List <OneExpression>(Out)));
                In.Clear();
                Out.Clear();
            }
            return(actual);
        }
コード例 #8
0
        public static IReadOnlyList <Instruction> Optimize(
            IReadOnlyList <Instruction> instructions,
            List <Optimization> basicBlockOptimizations = null,
            List <Optimization> allCodeOptimizations    = null,
            bool UnreachableCodeElimination             = false)
        {
            basicBlockOptimizations ??= new List <Optimization>();
            allCodeOptimizations ??= new List <Optimization>();

            var blocks = UnreachableCodeElimination ?
                         BasicBlockLeader.DivideLeaderToLeader(new ControlFlowGraph(instructions).GetInstructions()) :
                         BasicBlockLeader.DivideLeaderToLeader(instructions);

            if (basicBlockOptimizations.Count != 0)
            {
                for (var i = 0; i < blocks.Count; ++i)
                {
                    blocks[i] = OptimizeBlock(blocks[i], basicBlockOptimizations);
                }
            }

            var preResult = blocks.SelectMany(b => b.GetInstructions()).ToList();
            var result    = OptimizeAllCode(preResult, allCodeOptimizations);

            return(UnreachableCodeElimination ? new ControlFlowGraph(result).GetInstructions() : result);
        }
        public void NoOptimizationInNotReducibleGraph() // hardest
        {
            var TAC = GenTAC(@"var a, b, c, d, x, u, e, g, y, zz, i;
if a > b
{
    c = d;
    1:  x = e;
    goto 2;
}
else
{
    e = g;
    2: a = d;
    goto 1;
}");
            var availableExprOpt = GeneratorBasicBlockAfterOptimization(TAC);
            var graph            = new ControlFlowGraph(BasicBlockLeader.DivideLeaderToLeader(TAC));
            var expectedBlock    = graph.GetCurrentBasicBlocks();

            Assert.AreEqual(availableExprOpt.Count, expectedBlock.Count);

            var actual   = GetStringFromBlocks(availableExprOpt);
            var expected = GetStringFromBlocks(expectedBlock);

            CollectionAssert.AreEqual(actual, expected);
        }
コード例 #10
0
        public void OneRootLoopsTest()
        {
            var TAC = GenTAC(@"
var a, b;

54: a = 5;
b = 6;
goto 54;
goto 54;

");

            var cfg      = new ControlFlowGraph(BasicBlockLeader.DivideLeaderToLeader(TAC));
            var actual   = NaturalLoop.GetAllNaturalLoops(cfg);
            var expected = new List <List <BasicBlock> >()
            {
                new List <BasicBlock>()
                {
                    new BasicBlock(new List <Instruction>()
                    {
                        TAC[0], TAC[1], TAC[2]
                    })
                },
            };

            AssertSet(expected, actual);
        }
コード例 #11
0
        public void LabelAliveTest()
        {
            var TAC = GenTAC(@"
var a, b, c;
goto 3;
a = 54;
3: b = 11;
");

            var expected = new List <BasicBlock>()
            {
                new BasicBlock(new List <Instruction>()
                {
                    new Instruction("", "goto", "3", "", "")
                }),
                new BasicBlock(new List <Instruction>()
                {
                    new Instruction("", "assign", "54", "", "a")
                }),
                new BasicBlock(new List <Instruction>()
                {
                    new Instruction("3", "assign", "11", "", "b")
                }),
            };
            var actual = BasicBlockLeader.DivideLeaderToLeader(TAC);

            AssertSet(expected, actual);
        }
コード例 #12
0
        protected ControlFlowGraph BuildTACOptimizeCFG(string program)
        {
            var TAC       = GenTAC(program);
            var optResult = ThreeAddressCodeOptimizer.OptimizeAll(TAC);
            var blocks    = BasicBlockLeader.DivideLeaderToLeader(optResult);

            return(new ControlFlowGraph(blocks));
        }
        private IReadOnlyList <BasicBlock> GeneratorBasicBlockAfterOptimization(List <Instruction> TAC)
        {
            var cfg       = new ControlFlowGraph(BasicBlockLeader.DivideLeaderToLeader(TAC));
            var inOutData = new AvailableExpressions().Execute(cfg);

            AvailableExpressionsApplication.Execute(cfg, inOutData);
            return(cfg.GetCurrentBasicBlocks());
        }
コード例 #14
0
        private (List <BasicBlock> basicBlocks, InOutData <IEnumerable <Instruction> > inOutInfo) GenGraphAndGetInOutInfo(string program)
        {
            var TAC       = GenTAC(program);
            var blocks    = BasicBlockLeader.DivideLeaderToLeader(TAC);
            var cfg       = new ControlFlowGraph(blocks);
            var inOutInfo = new ReachingDefinitionBinary().Execute(cfg);

            return(blocks, inOutInfo);
        }
コード例 #15
0
        public void InputAssignsNAC()
        {
            var TAC    = GenTAC(@"
var a, x, c;
input(c);
");
            var blocks = BasicBlockLeader.DivideLeaderToLeader(TAC);
            var cfg    = new ControlFlowGraph(blocks);
            var InOut  = new ConstPropagation().ExecuteNonGeneric(cfg);

            Assert.AreEqual(LatticeTypeData.NAC, InOut.OUT[blocks[0]]["c"].Type);
        }
コード例 #16
0
        public void OneAssign()
        {
            var TAC    = GenTAC(@"
var a,b,c;
a = 5;
");
            var blocks = BasicBlockLeader.DivideLeaderToLeader(TAC);
            var cfg    = new ControlFlowGraph(blocks);
            var InOut  = new ConstPropagation().ExecuteNonGeneric(cfg);

            Assert.AreEqual(InOut.OUT[blocks[0]]["a"].Type, LatticeTypeData.CONST);
            Assert.AreEqual("5", InOut.OUT[blocks[0]]["a"].ConstValue);
        }
コード例 #17
0
        public void TestNoBlocks()
        {
            var TAC    = GenTAC(@"
var a,b,c;
");
            var blocks = BasicBlockLeader.DivideLeaderToLeader(TAC);

            Assert.AreEqual(0, blocks.Count);
            var cfg   = new ControlFlowGraph(blocks);
            var InOut = new ConstPropagation().ExecuteNonGeneric(cfg);

            Assert.AreEqual(2, InOut.IN.Count);
            Assert.AreEqual(2, InOut.OUT.Count);
        }
コード例 #18
0
        private List <(HashSet <string> IN, HashSet <string> OUT)> Execute(List <Instruction> TAC)
        {
            var blocks = BasicBlockLeader.DivideLeaderToLeader(TAC);
            var cfg    = new ControlFlowGraph(blocks);

            var liveAct = new LiveVariableAnalysis();

            liveAct.ExecuteInternal(cfg);

            var listAct = liveAct.dictInOut
                          .Select(x => x.Value)
                          .Select(y => (y.IN as HashSet <string>, y.OUT as HashSet <string>));

            return(listAct.ToList());
        }
コード例 #19
0
        public void EliminationdMultyBlocksTest2()
        {
            var TAC = GenTAC(@"
var a, b, c;

goto 1;
111:a = 1; 
goto 55; 
55: goto 10; 
10: goto 111; 
if a>a goto 10; 
else goto 111; 
 
c = c; 
if a==b 
	b = b; 

2: a = -1; 
b = -a; 
c = -(a+b); 
a = !b; 
c = !(a == b); 
1: b = 3;
goto 2;
");
            var cfg = new ControlFlowGraph(BasicBlockLeader.DivideLeaderToLeader(TAC));

            var actual = cfg.GetCurrentBasicBlocks().ToList();

            var expected = new List <BasicBlock>()
            {
                new BasicBlock(new List <Instruction>()
                {
                    TAC[0]
                }),
                new BasicBlock(new List <Instruction>()
                {
                    TAC[17], TAC[18], TAC[19], TAC[20], TAC[21], TAC[22], TAC[23], TAC[24], TAC[25], TAC[26], TAC[27], TAC[28]
                }),
                new BasicBlock(new List <Instruction>()
                {
                    TAC[29], TAC[30]
                }),
            };


            AssertSet(expected, actual.Skip(1).Take(actual.Count - 2).ToList());
        }
コード例 #20
0
        public void WithoutCycles()
        {
            var TAC      = GenTAC(@"
var a, b;
a = 5;
if b != 2
{
    a = 6;
}
a = 8;
");
            var blocks   = BasicBlockLeader.DivideLeaderToLeader(TAC);
            var cfg      = new ControlFlowGraph(blocks);
            var result   = new CFGregions(cfg);
            var actual   = result.Regions.Select(x => (x.edges?.Count ?? 0, x.includedRegions?.Count ?? 0)).ToArray();
            var expected = new[] {
コード例 #21
0
        public void PropagateTwoVariants2()
        {
            var TAC = GenTAC(@"
var a, x, c;
x = 10;
a = 20;
goto 666;
666: c = a + x;
");

            var blocks = BasicBlockLeader.DivideLeaderToLeader(TAC);
            var cfg    = new ControlFlowGraph(blocks);
            var InOut  = new ConstPropagation().ExecuteNonGeneric(cfg);

            Assert.AreEqual(InOut.OUT[blocks[1]]["c"].Type, LatticeTypeData.CONST);
            Assert.AreEqual(InOut.OUT[blocks[1]]["c"].ConstValue, "30");
        }
コード例 #22
0
        public void VariableAndConst()
        {
            var TAC    = GenTAC(@"
var u,p,v;
u = 3;
p = u + 2;
");
            var blocks = BasicBlockLeader.DivideLeaderToLeader(TAC);
            var cfg    = new ControlFlowGraph(blocks);
            var InOut  = new ConstPropagation().ExecuteNonGeneric(cfg);

            Assert.AreEqual(InOut.OUT[blocks[0]]["u"].Type, LatticeTypeData.CONST);
            Assert.AreEqual(InOut.OUT[blocks[0]]["p"].Type, LatticeTypeData.CONST);

            Assert.AreEqual("3", InOut.OUT[blocks[0]]["u"].ConstValue);
            Assert.AreEqual("5", InOut.OUT[blocks[0]]["p"].ConstValue);
        }
コード例 #23
0
        public void EliminationdMultyBlocksTest1()
        {
            var TAC = GenTAC(@"
var a, b, c;

goto 1;
111:a = 1; 
goto 55; 
55: goto 10; 
10: goto 111; 
if a>a goto 10; 
else goto 111; 
 
c = c; 
if a==b 
	b = b; 
 
a = -1; 
b = -a; 
c = -(a+b); 
a = !b; 
c = !(a == b); 
1: b = 3;
");
            var cfg = new ControlFlowGraph(BasicBlockLeader.DivideLeaderToLeader(TAC));

            var actual = cfg.GetCurrentBasicBlocks().ToList();

            var expected = new List <BasicBlock>()
            {
                new BasicBlock(new List <Instruction>()
                {
                    new Instruction("", "goto", "1", "", "")
                }),
                new BasicBlock(new List <Instruction>()
                {
                    new Instruction("1", "assign", "3", "", "b")
                }),
            };


            AssertSet(expected, actual.Skip(1).Take(actual.Count - 2).ToList());
        }
コード例 #24
0
        public void WhileProp()
        {
            var TAC = GenTAC(@"
var a, b, x, c;
while x > 1
{
	a = 2;
	b = 5;
}
c = a + b;
");

            var blocks = BasicBlockLeader.DivideLeaderToLeader(TAC);
            var cfg    = new ControlFlowGraph(blocks);
            var InOut  = new ConstPropagation().ExecuteNonGeneric(cfg);

            Assert.AreEqual(InOut.OUT[blocks[3]]["c"].Type, LatticeTypeData.CONST);
            Assert.AreEqual(InOut.OUT[blocks[3]]["c"].ConstValue, "7");
        }
コード例 #25
0
        public void ForProp()
        {
            var TAC = GenTAC(@"
var a, b, x, c;
for x=1,10
{
	a = 2;
	b = 2;
}
c = a + b;
");

            var blocks = BasicBlockLeader.DivideLeaderToLeader(TAC);
            var cfg    = new ControlFlowGraph(blocks);
            var InOut  = new ConstPropagation().ExecuteNonGeneric(cfg);

            Assert.AreEqual(LatticeTypeData.CONST, InOut.OUT[blocks[3]]["c"].Type);
            Assert.AreEqual("4", InOut.OUT[blocks[3]]["c"].ConstValue);
        }
コード例 #26
0
        public void TwoConstValues()
        {
            var TAC    = GenTAC(@"
var a, x, c;
input(c);
if c > 5
    x = 10;
else
    input(c);
if c > 5
    x = 20;
a = x;
");
            var blocks = BasicBlockLeader.DivideLeaderToLeader(TAC);
            var cfg    = new ControlFlowGraph(blocks);
            var InOut  = new ConstPropagation().ExecuteNonGeneric(cfg);

            Assert.AreEqual(LatticeTypeData.NAC, InOut.OUT[blocks[5]]["a"].Type);
            Assert.AreEqual(LatticeTypeData.NAC, InOut.OUT[blocks[5]]["x"].Type);
        }
コード例 #27
0
        public static List <Instruction> Optimize(
            List <Instruction> instructions,
            List <Optimization> basicBlockOptimizations = null,
            List <Optimization> allCodeOptimizations    = null)
        {
            basicBlockOptimizations = basicBlockOptimizations ?? new List <Optimization>();
            allCodeOptimizations    = allCodeOptimizations ?? new List <Optimization>();

            var blocks = BasicBlockLeader.DivideLeaderToLeader(instructions);

            for (var i = 0; i < blocks.Count; ++i)
            {
                blocks[i] = OptimizeBlock(blocks[i], basicBlockOptimizations);
            }

            var preResult = blocks.SelectMany(b => b.GetInstructions()).ToList();
            var result    = OptimizeAllCode(preResult, allCodeOptimizations);

            return(result);
        }
コード例 #28
0
        public void ComplicatedEquation()
        {
            var TAC    = GenTAC(@"
var a,b,c;
a = 2;
b = 3;
c = a * b - 2;
");
            var blocks = BasicBlockLeader.DivideLeaderToLeader(TAC);
            var cfg    = new ControlFlowGraph(blocks);
            var InOut  = new ConstPropagation().ExecuteNonGeneric(cfg);

            Assert.AreEqual(InOut.OUT[blocks[0]]["a"].Type, LatticeTypeData.CONST);
            Assert.AreEqual(InOut.OUT[blocks[0]]["b"].Type, LatticeTypeData.CONST);
            Assert.AreEqual(InOut.OUT[blocks[0]]["c"].Type, LatticeTypeData.CONST);

            Assert.AreEqual("2", InOut.OUT[blocks[0]]["a"].ConstValue);
            Assert.AreEqual("3", InOut.OUT[blocks[0]]["b"].ConstValue);
            Assert.AreEqual("4", InOut.OUT[blocks[0]]["c"].ConstValue);
        }
コード例 #29
0
        public void IrreducibilityGraphTest2()
        {
            var TAC = GenTAC(@"
var a, b, c, d, x, u, e,g, y,zz,i;
for i = 1, 10
{
a = b;
1: c = d;
goto 2;
}
2: x = u;
goto 1;
");

            var cfg      = new ControlFlowGraph(BasicBlockLeader.DivideLeaderToLeader(TAC));
            var actual   = NaturalLoop.GetAllNaturalLoops(cfg);
            var expected = new List <List <BasicBlock> >();

            AssertSet(expected, actual);
        }
コード例 #30
0
        public void VariableAndConst3()
        {
            var TAC    = GenTAC(@"
var a,b,c;
b = 3;
goto 11;
c = b + 2;
11: a = 7;
");
            var blocks = BasicBlockLeader.DivideLeaderToLeader(TAC);
            var cfg    = new ControlFlowGraph(blocks);
            var InOut  = new ConstPropagation().ExecuteNonGeneric(cfg);

            Assert.AreEqual(LatticeTypeData.CONST, InOut.OUT[blocks[2]]["b"].Type);
            Assert.AreEqual(LatticeTypeData.CONST, InOut.OUT[blocks[2]]["a"].Type);
            Assert.AreEqual(false, InOut.OUT[blocks[2]].ContainsKey("c"));

            Assert.AreEqual("3", InOut.OUT[blocks[2]]["b"].ConstValue);
            Assert.AreEqual("7", InOut.OUT[blocks[2]]["a"].ConstValue);
        }