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()); }
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); }
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); }
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()); }
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); }
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); }
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); }
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); }
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); }
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); }
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()); }
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); }
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); }
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); }
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); }
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()); }
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()); }
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[] {
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"); }
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); }
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()); }
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"); }
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); }
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); }
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); }
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); }
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); }
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); }