/// <summary> /// Конструктор /// </summary> /// <param name="code">экземпляр программы в формате трехадресного кода</param> public ControlFlowGraph(TACode code) { Code = code; _cfgNodes = new List<BasicBlock>(); CreateCFGNodes(); }
public static NumeratedGraph StraightOrder(this TACode code) { var graph = new NumeratedGraph(code, null); graph.Numerator = GraphNumerator.BackOrder(graph).Reverse(graph); return(graph); }
public TACode ApplyAllOptimizations(TACode code) { List <IOptimization> o1Optimizations = BasicBlockOptimizationList(); var canApplyAny = true; while (canApplyAny) { canApplyAny = false; var blocks = code.CreateBasicBlockList().ToList(); var codeList = new List <Node>(); foreach (var b in blocks) { var block = b.CodeList.ToList(); for (int i = 0; i < o1Optimizations.Count; i++) { block = o1Optimizations[i].Optimize(block, out var applied); canApplyAny = canApplyAny || applied; } codeList.AddRange(block); } code = new TACode(); code.CodeList = codeList; foreach (var line in code.CodeList) { code.LabeledCode[line.Label] = line; } } return(code); }
public void GenerateCFG(TACode code) { try { var cfg = new ControlFlowGraph(code); string graph = BuildDotGraph(cfg); File.WriteAllText(@"cfg_graph.txt", graph); var processQuery = new GetStartProcessQuery(); var processStartInfoQuery = new GetProcessStartInfoQuery(); var registerLayout = new RegisterLayoutPluginCommand(processStartInfoQuery, processQuery); var wrapper = new GraphGeneration(processQuery, processStartInfoQuery, registerLayout) { RenderingEngine = Enums.RenderingEngine.Dot }; byte[] output = wrapper.GenerateGraph(graph, Enums.GraphReturnType.Png); using (var stream = new MemoryStream(output)) { var image = Image.FromStream(stream); GenerationCompleted(null, image); } CfgGenerated(null, cfg); } catch (Exception ex) { GenerationErrored(null, ex); } }
public ControlFlowGraph(TACode code) { _code = code; _blockList = _code.CreateBasicBlockList().ToList(); CFGNodes = new SortedSet <CFGNode>(); CreateCFGNodes(); }
public static TACode LabelCode(TACode code) { foreach (var l in code.CodeList.ToList()) { code.LabeledCode[l.Label] = l; } return(code); }
public InOutData <Dictionary <Guid, VarValue> > TempFunc(TACode taCode, ControlFlowGraph cfg) { Operations ops = new Operations(taCode); TransferFunction f = new TransferFunction(); IterativeAlgorithm itAlg = new IterativeAlgorithm(); var result = itAlg.Analyze(cfg, ops, f); return(result); }
public VarInfoTable(TACode code) { foreach (var line in code.CodeList.OfType <Assign>()) { var v = line.Result; base[v.Id] = new VarInfo(); } this.code = code; }
/// <summary> /// Конструктор для TransferFunction /// </summary> /// <param name="code">Необходим для списка выражений-присвоений</param> public TransferFunction(TACode code) { AssignNodes = new List <Assign>(); foreach (var node in code.CodeList) { if ((node is Assign ass) && (!(ass.Left is null) && !(ass.Right is null)) && (ass.Left is Var || ass.Right is Var)) { AssignNodes.Add(ass); } } }
public void GenerateIlCode(TACode code) { try { var trans = new TAcode2ILcodeTranslator(); trans.Translate(code); _ilProgram = trans; GenerationCompleted(null, trans); } catch (Exception ex) { GenerationErrored(null, ex); } }
private TACode ApplyOptimizations(TACode code) { var optList = BlockOptimizationList(); bool canApplyAny = true; TACode newCode = code; while (canApplyAny) { canApplyAny = false; var codeList = newCode.CreateBasicBlockList(); newCode = new TACode(); foreach (var b in codeList) { List <Node> block = b.CodeList.ToList(); foreach (var opt in optList) { block = opt.Optimize(block, out var applied); canApplyAny = canApplyAny || applied; } foreach (var node in block) { newCode.AddNode(node); } } foreach (var line in newCode.CodeList) { newCode.LabeledCode[line.Label] = line; } } if (OptimizationList[Optimizations.GlobalConstProp]) { var opt = new GlobalConstantPropogationAlt(newCode); newCode = opt.Optimize(); AllOptimizations.LabelCode(newCode); } if (RemoveDeadVariables) { var rmOpt = new RemoveDeadVariablesCFG(newCode); newCode = rmOpt.CodeNew; } return(newCode); }
public Operations(TACode code) { upper = new HashSet <Guid>(); foreach (var node in code.CodeList) { //Если узел - присваивание и хотя бы один операнд - это переменная, то добавляем его в верхнюю границу if (node is Assign ass && (!(ass.Left is null) && !(ass.Right is null))) { if (ass.Left is Var || ass.Right is Var) { upper.Add(ass.Label); } } } }
public Operations(TACode code) { Lower = new VarInfoTable(code); var keys = Lower.Keys.ToArray(); foreach (var k in keys) { Lower[k] = new VarInfo(VarInfo.Flag.NAC); } Upper = new VarInfoTable(code); foreach (var k in keys) { Upper[k] = new VarInfo(VarInfo.Flag.UNDEF); } }
public void GenerateThreeAddrCode(object sender, Parser.AST.BlockNode root) { try { var visitor = new TACodeVisitor(); root.Visit(visitor); TACode code = ApplyOptimizations(visitor.Code); GenerationCompleted(null, code); PostProcess(code); } catch (Exception ex) { GenerationErrored(null, ex); } }
public Operations(TACode code) { upper = new Dictionary <Guid, VarValue>(); foreach (var node in code.CodeList) { if (node is Assign) { var asNode = node as Assign; // т.к. node as Assign всегда Var верхние значения инициализированы как NAC if (!upper.ContainsKey((asNode.Result as Var).Id)) { upper.Add((asNode.Result as Var).Id, new VarValue(asNode.Result)); } if (asNode.Left is Var && !upper.ContainsKey((asNode.Left as Var).Id)) { upper.Add((asNode.Left as Var).Id, new VarValue(asNode.Left as Var)); } if (asNode.Right is Var && !upper.ContainsKey((asNode.Right as Var).Id)) { upper.Add((asNode.Right as Var).Id, new VarValue(asNode.Right as Var)); } } } lower = new Dictionary <Guid, VarValue>(); foreach (var node in code.CodeList) { if (node is Assign) { var asNode = node as Assign; // UNDEF if (!lower.ContainsKey((asNode.Result as Var).Id)) { lower.Add((asNode.Result as Var).Id, new VarValue()); } if (asNode.Left is Var && !lower.ContainsKey((asNode.Left as Var).Id)) { lower.Add((asNode.Left as Var).Id, new VarValue()); } if (asNode.Right is Var && !lower.ContainsKey((asNode.Right as Var).Id)) { lower.Add((asNode.Right as Var).Id, new VarValue()); } } } }
public TACode Optimize(TACode taCode, out bool applied) { var app = false; var visited = new Dictionary <Guid, bool>(); ControlFlowGraph cfg = new ControlFlowGraph(taCode); var ioData = TempFunc(taCode, cfg); foreach (var node in taCode.CodeList.ToList().OfType <Assign>()) { visited[node.Result.Id] = false; } for (int j = taCode.CodeList.Count() - 1; j > 0; j--) { var node = taCode.CodeList.ElementAt(j) as Assign; if (node != null) { for (int i = 0; i < cfg.CFGNodes.Count(); i++) { if (ioData[cfg.CFGNodes.ElementAt(i)].Item1.ContainsKey(node.Result.Id) && ioData[cfg.CFGNodes.ElementAt(i)].Item1[node.Result.Id].varType is VarValue.Type.CONST) { if (visited[node.Result.Id] == true) { break; } visited[node.Result.Id] = true; node.Right = ioData[cfg.CFGNodes.ElementAt(i)].Item1[node.Result.Id].value; node.Left = null; node.Operation = OpCode.Copy; taCode.CodeList[j] = node; } } } } applied = app; return(taCode); }
public void ReachingDefenitionTest0() { var taCode = new TACode(); var ass1 = new Assign { Left = new IntConst(1000), Operation = OpCode.Minus, Right = new IntConst(5), Result = new Var() }; var ass2 = new Assign { Left = new IntConst(2000), Operation = OpCode.Copy, Result = new Var() }; var ass3 = new Assign { Operation = OpCode.Copy, Right = new IntConst(3000), Result = new Var() }; var ass4 = new Assign { Left = ass1.Result, Operation = OpCode.Plus, Right = new IntConst(1), Result = ass1.Result }; ass4.IsLabeled = true; var ass5 = new Assign { Left = ass2.Result, Operation = OpCode.Minus, Right = new IntConst(4), Result = ass2.Result }; var ass6 = new Assign { Operation = OpCode.Copy, Right = new IntConst(4000), Result = ass3.Result }; var ass7 = new Assign { Operation = OpCode.Copy, Right = new IntConst(5000), Result = ass1.Result }; ass7.IsLabeled = true; var ifgt1 = new IfGoto { Condition = new IntConst(1), TargetLabel = ass7.Label }; var ifgt2 = new IfGoto { Condition = new IntConst(2), TargetLabel = ass4.Label }; var empty = new Empty { }; { taCode.AddNode(ass1); taCode.AddNode(ass2); taCode.AddNode(ass3); taCode.AddNode(ass4); taCode.AddNode(ass5); taCode.AddNode(ifgt1); taCode.AddNode(ass6); taCode.AddNode(ass7); taCode.AddNode(ifgt2); taCode.AddNode(empty); } var cfg = new ControlFlowGraph(taCode); taCode.CreateBasicBlockList(); var op = new Operations(taCode); var tf = new TransferFunction(taCode); var tmp = taCode.ToString(); var(gen, kill) = tf.GetGenAndKill(cfg.CFGNodes.ElementAt(0), op); Assert.True(gen.SetEquals(new HashSet <Guid> { ass1.Label, ass2.Label, ass3.Label })); Assert.True(kill.SetEquals(new HashSet <Guid> { ass4.Label, ass5.Label, ass6.Label, ass7.Label })); (gen, kill) = tf.GetGenAndKill(cfg.CFGNodes.ElementAt(1), op); Assert.True(gen.SetEquals(new HashSet <Guid> { ass4.Label, ass5.Label })); Assert.True(kill.SetEquals(new HashSet <Guid> { ass1.Label, ass2.Label, ass7.Label })); (gen, kill) = tf.GetGenAndKill(cfg.CFGNodes.ElementAt(2), op); Assert.True(gen.SetEquals(new HashSet <Guid> { ass6.Label })); Assert.True(kill.SetEquals(new HashSet <Guid> { ass3.Label })); (gen, kill) = tf.GetGenAndKill(cfg.CFGNodes.ElementAt(3), op); Assert.True(gen.SetEquals(new HashSet <Guid> { ass7.Label })); Assert.True(kill.SetEquals(new HashSet <Guid> { ass1.Label, ass4.Label })); var inout = new GenericIterativeAlgorithm <HashSet <Guid> >() { Finish = (a, b) => { var(a1, a2) = a; var(b1, b2) = b; return(!a2.Except(b2).Any()); }, Comparer = (x, y) => !x.Except(y).Any(), Fill = () => (op.Lower, op.Lower), DebugToString = (x) => x.Aggregate("", (s, y) => s + ", " + TACodeNameManager.Instance[y]) }.Analyze(cfg, op, tf);
public TransferFunction(TACode ta) => taCode = ta;
public void Test1() { var taCode = new TACode(); var assgn1 = new Assign() { Left = null, Operation = OpCode.Copy, Right = new IntConst(91), Result = new Var("b") }; var assgn2 = new Assign() { Left = null, Operation = OpCode.Copy, Right = assgn1.Result, Result = new Var("c") }; var assgn3 = new Assign() { Left = assgn1.Result, Operation = OpCode.Plus, Right = new IntConst(10), Result = new Var("d") }; var ifgtH = new IfGoto { Condition = new IntConst(1), TargetLabel = assgn3.Label }; assgn3.IsLabeled = true; var assgn4 = new Assign() { Left = null, Operation = OpCode.Copy, Right = new IntConst(2), Result = new Var("j") }; var assgn5 = new Assign() { Left = null, Operation = OpCode.Copy, Right = new IntConst(0), Result = assgn3.Result }; var assgn6 = new Assign() { Left = null, Operation = OpCode.Copy, Right = assgn2.Result, Result = assgn3.Result }; var ifgtX = new IfGoto { Condition = new IntConst(1), TargetLabel = assgn6.Label }; assgn6.IsLabeled = true; taCode.AddNode(assgn1); taCode.AddNode(assgn2); taCode.AddNode(ifgtH); taCode.AddNode(assgn3); taCode.AddNode(assgn4); taCode.AddNode(assgn5); taCode.AddNode(ifgtX); taCode.AddNode(assgn6); var cfg = new ControlFlowGraph(taCode); IterativeAlgorithmAV ItAV = new IterativeAlgorithmAV(cfg); Assert.AreEqual(ItAV.IN.ElementAt(0).Value.Count, 0); Assert.AreEqual(ItAV.IN.ElementAt(1).Value.ElementAt(0), assgn1.Result); Assert.AreEqual(ItAV.IN.ElementAt(1).Value.ElementAt(1), assgn2.Result); Assert.AreEqual(ItAV.IN.ElementAt(2).Value.ElementAt(0), assgn2.Result); Assert.AreEqual(ItAV.OUT.ElementAt(0).Value.ElementAt(0), assgn1.Result); Assert.AreEqual(ItAV.OUT.ElementAt(0).Value.ElementAt(1), assgn2.Result); Assert.AreEqual(ItAV.OUT.ElementAt(1).Value.ElementAt(0), assgn2.Result); Assert.AreEqual(ItAV.OUT.ElementAt(2).Value.Count, 0); }
public void ReachingExpressionsTest1() { var taCode = new TACode(); //TAC выглядит следующим образом /** * 0) t0 = 3 | * 1) t1 = 5 + t0 | B1 * 2) t2 = t1 + t0 | * * * 3) t3 = 4 + t2 | * 4) t1 = 10 | B2 * 5) if (1) goto 3) | * * * 6) t4 = t1 + 5 | * 7) t5 = t3 + t0 | * 8) t0 = 100 | B3 * 9) if (2) goto 6) | * * * 10) t6 = t5 + 10 | * 11) t7 = t6 + 10 | * 12) t8 = t6 + t7 | B4 * 13) t6 = 3 | * 14) t5 = 100 | * **/ var ass1 = new Assign { Operation = OpCode.Plus, Right = new IntConst(3), Result = new Var() }; var ass2 = new Assign { Left = new IntConst(5), Operation = OpCode.Plus, Right = ass1.Result, Result = new Var() }; var ass3 = new Assign { Left = ass2.Result, Operation = OpCode.Plus, Right = ass1.Result, Result = new Var() }; var ass4 = new Assign { Left = new IntConst(4), Operation = OpCode.Plus, Right = ass3.Result, Result = new Var() }; var ass5 = new Assign { Operation = OpCode.Plus, Right = new IntConst(10), Result = ass2.Result }; var ifgt1 = new IfGoto { Condition = new IntConst(1), TargetLabel = ass4.Label }; ass4.IsLabeled = true; var ass6 = new Assign { Left = ass2.Result, Operation = OpCode.Plus, Right = new IntConst(5), Result = new Var() }; var ass7 = new Assign { Left = ass4.Result, Operation = OpCode.Plus, Right = ass1.Result, Result = new Var() }; var ass8 = new Assign { Operation = OpCode.Plus, Right = new IntConst(100), Result = ass1.Result }; var ifgt2 = new IfGoto { Condition = new IntConst(2), TargetLabel = ass6.Label }; ass6.IsLabeled = true; var ass9 = new Assign { Left = ass7.Result, Operation = OpCode.Plus, Right = new IntConst(10), Result = new Var() }; var ass10 = new Assign { Left = ass9.Result, Operation = OpCode.Plus, Right = new IntConst(10), Result = new Var() }; var ass11 = new Assign { Left = ass9.Result, Operation = OpCode.Plus, Right = ass10.Result, Result = new Var() }; var ass12 = new Assign { Operation = OpCode.Plus, Right = new IntConst(3), Result = ass9.Result }; var ass13 = new Assign { Operation = OpCode.Plus, Right = new IntConst(100), Result = ass7.Result }; taCode.AddNode(ass1); taCode.AddNode(ass2); taCode.AddNode(ass3); taCode.AddNode(ass4); taCode.AddNode(ass5); taCode.AddNode(ifgt1); taCode.AddNode(ass6); taCode.AddNode(ass7); taCode.AddNode(ass8); taCode.AddNode(ifgt2); taCode.AddNode(ass9); taCode.AddNode(ass10); taCode.AddNode(ass11); taCode.AddNode(ass12); taCode.AddNode(ass13); /** CFG имеет следующий вид * * B1 * | * | ____ * v / \ * B2-v______| * | * | ____ * v / \ * B3-v______| * | * | * V * B4 * */ var cfg = new ControlFlowGraph(taCode); /**************************Reaching definition test*************************/ var op = new Operations(taCode); var algo = new IterativeAlgorithm(); var transFunc = new TransferFunction(taCode); var inout = algo.Analyze(cfg, op, transFunc); //Тестирование множест e_gen и e_kill для каждого базового блока var(e_gen, e_kill) = transFunc.GetEGenEKill(cfg.CFGNodes.ElementAt(0)); Assert.True(e_gen.SetEquals(new HashSet <Guid> { ass2.Label, ass3.Label })); Assert.True(e_kill.SetEquals(new HashSet <Guid> { ass4.Label, ass6.Label, ass7.Label })); (e_gen, e_kill) = transFunc.GetEGenEKill(cfg.CFGNodes.ElementAt(1)); Assert.True(e_gen.SetEquals(new HashSet <Guid> { ass4.Label })); Assert.True(e_kill.SetEquals(new HashSet <Guid> { ass3.Label, ass6.Label, ass7.Label })); (e_gen, e_kill) = transFunc.GetEGenEKill(cfg.CFGNodes.ElementAt(2)); Assert.True(e_gen.SetEquals(new HashSet <Guid> { ass6.Label })); Assert.True(e_kill.SetEquals(new HashSet <Guid> { ass2.Label, ass3.Label, ass7.Label, ass9.Label })); (e_gen, e_kill) = transFunc.GetEGenEKill(cfg.CFGNodes.ElementAt(3)); Assert.True(e_gen.SetEquals(new HashSet <Guid> { })); Assert.True(e_kill.SetEquals(new HashSet <Guid> { ass9.Label, ass10.Label, ass11.Label })); //Текстирование IN/OUT множеств для каждого ББл var trueInOut = new DFA.InOutData <HashSet <System.Guid> >(); trueInOut.Add(cfg.CFGNodes.ElementAt(0), (new HashSet <Guid>(), new HashSet <Guid> { ass2.Label, ass3.Label }) ); trueInOut.Add(cfg.CFGNodes.ElementAt(1), (new HashSet <Guid> { ass2.Label, ass3.Label }, new HashSet <Guid> { ass2.Label, ass4.Label }) ); trueInOut.Add(cfg.CFGNodes.ElementAt(2), (new HashSet <Guid> { ass2.Label, ass4.Label }, new HashSet <Guid> { ass4.Label, ass6.Label }) ); trueInOut.Add(cfg.CFGNodes.ElementAt(3), (new HashSet <Guid> { ass4.Label, ass6.Label }, new HashSet <Guid> { ass4.Label, ass6.Label }) ); foreach (var x in cfg.CFGNodes) { HashSet <Guid> toutItem1 = trueInOut[x].Item1; HashSet <Guid> outItem1 = inout[x].Item1; HashSet <Guid> toutItem2 = trueInOut[x].Item2; HashSet <Guid> outItem2 = inout[x].Item2; var inEq = toutItem1.SetEquals(outItem1); var outEq = toutItem2.SetEquals(outItem2); Assert.True(inEq && outEq); } }
public void Test1() { var taCodeConstantFolding = new TACode(); var assgn1 = new Assign() { Left = null, Operation = OpCode.Copy, Right = new Var(), Result = new Var() }; var assgn2 = new Assign() { Left = new IntConst(20), Operation = OpCode.Mul, Right = new IntConst(3), Result = new Var() }; var assgn3 = new Assign() { Left = new IntConst(10), Operation = OpCode.Plus, Right = new IntConst(1), Result = new Var() }; var assgn4 = new Assign() { Left = new IntConst(100), Operation = OpCode.Div, Right = new IntConst(50), 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() }; taCodeConstantFolding.AddNode(assgn1); taCodeConstantFolding.AddNode(assgn2); taCodeConstantFolding.AddNode(assgn3); taCodeConstantFolding.AddNode(assgn4); taCodeConstantFolding.AddNode(assgn5); taCodeConstantFolding.AddNode(assgn6); var optConstFold = new ConstantFolding(); optConstFold.Optimize(taCodeConstantFolding.CodeList.ToList(), out var applConstFold); /* * 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 */ Assert.AreEqual(assgn2.Right, 60); Assert.AreEqual(assgn3.Right, 11); Assert.AreEqual(assgn4.Right, 2); Assert.AreEqual(assgn5.Right, 10); Assert.True(true); }
private TACode GetTestGraph1() { var taCode = new TACode(); var ass1 = new Assign { Left = new IntConst(3), 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); return(taCode); }
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); }
public void Translate(TACode tACode) { gen = new GenCodeCreator(); gen.Emit(OpCodes.Nop); foreach (var currentInstuction in tACode.CodeList) { if (currentInstuction.IsLabeled) { var curLabel = gen.DefineLabel(); labels.Add(currentInstuction.Label.ToString(), curLabel); } } foreach (var currentInstuction in tACode.CodeList) { if (currentInstuction.IsLabeled) { gen.Emit(OpCodes.Nop); gen.MarkLabel(labels[currentInstuction.Label.ToString()]); } switch (currentInstuction) { case Assign assignNode: try { if (!vars.ContainsKey(assignNode.Result.Id.ToString())) { vars.Add(assignNode.Result.Id.ToString(), gen.DeclareLocal(typeof(int))); } if (assignNode.Left != null) { if (assignNode.Left is Var) { gen.Emit(OpCodes.Ldloc, vars[(assignNode.Left as Var).Id.ToString()]); } else { gen.Emit(OpCodes.Ldc_I4, (assignNode.Left as IntConst).Num); } } if (assignNode.Right is Var) { gen.Emit(OpCodes.Ldloc, vars[(assignNode.Right as Var).Id.ToString()]); } else { gen.Emit(OpCodes.Ldc_I4, (assignNode.Right as IntConst).Num); } switch (assignNode.Operation) { case ThreeAddrCode.OpCode.Plus: if (assignNode.Left != null) { gen.Emit(OpCodes.Add); } break; case ThreeAddrCode.OpCode.Minus: if (assignNode.Left != null) { gen.Emit(OpCodes.Sub); } else { gen.Emit(OpCodes.Neg); } break; case ThreeAddrCode.OpCode.Mul: gen.Emit(OpCodes.Mul); break; case ThreeAddrCode.OpCode.Div: gen.Emit(OpCodes.Div); break; case ThreeAddrCode.OpCode.UnaryMinus: gen.Emit(OpCodes.Neg); break; case ThreeAddrCode.OpCode.Copy: break; case ThreeAddrCode.OpCode.Greater: gen.Emit(OpCodes.Cgt); break; case ThreeAddrCode.OpCode.Less: gen.Emit(OpCodes.Clt); break; case ThreeAddrCode.OpCode.GreaterEq: gen.Emit(OpCodes.Clt); gen.Emit(OpCodes.Ldc_I4_0); gen.Emit(OpCodes.Ceq); break; case ThreeAddrCode.OpCode.LessEq: gen.Emit(OpCodes.Cgt); gen.Emit(OpCodes.Ldc_I4_0); gen.Emit(OpCodes.Ceq); break; case ThreeAddrCode.OpCode.Equal: gen.Emit(OpCodes.Ceq); break; case ThreeAddrCode.OpCode.NotEqual: gen.Emit(OpCodes.Ceq); gen.Emit(OpCodes.Ldc_I4_0); gen.Emit(OpCodes.Ceq); break; case ThreeAddrCode.OpCode.Not: gen.Emit(OpCodes.Ldc_I4_0); gen.Emit(OpCodes.Ceq); break; } ; gen.Emit(OpCodes.Stloc, vars[assignNode.Result.Id.ToString()]); } catch (KeyNotFoundException e) { throw new UsingOfUndefiendVariableException("Невозможно транслировать в il-код." + " Использование необъявленной переменной"); } break; case Empty emptyNode: gen.Emit(OpCodes.Nop); break; case IfGoto ifgotoNode: try { var curLabel = gen.DefineLabel(); if (ifgotoNode.Condition is Var) { gen.Emit(OpCodes.Ldloc, vars[(ifgotoNode.Condition as Var).Id.ToString()]); } else { gen.Emit(OpCodes.Ldc_I4, (ifgotoNode.Condition as IntConst).Num); } gen.Emit(OpCodes.Brfalse, curLabel); gen.Emit(OpCodes.Br, labels[ifgotoNode.TargetLabel.ToString()]); gen.Emit(OpCodes.Nop); gen.MarkLabel(curLabel); } catch (KeyNotFoundException e) { throw new UsingOfUndefiendVariableException("Невозможно транслировать в il-код." + " Использование необъявленной переменной или переход по необъявлеенной метке"); } break; case Goto gotoNode: try { gen.Emit(OpCodes.Br, labels[gotoNode.TargetLabel.ToString()]); } catch (KeyNotFoundException e) { throw new UsingOfUndefiendVariableException("Невозможно транслировать в il-код." + " Переход по необъявленной метке"); } break; case Print printNode: try { if (printNode.Data is Var) { gen.Emit(OpCodes.Ldloc, vars[(printNode.Data as Var).Id.ToString()]); } else { gen.Emit(OpCodes.Ldc_I4, (printNode.Data as IntConst).Num); } gen.EmitWriteLine(); break; } catch (KeyNotFoundException e) { throw new UsingOfUndefiendVariableException("Невозможно транслировать в il-код." + " Использование необъявленной переменной"); } default: throw new Exception("Unknow type of node of TAcode"); } } gen.Emit(OpCodes.Ret); }
private void PostProcess(TACode code) { string postProcessCode = OutputSanitizer.Sanitize(code.ToString(), OutputSanitizer.SanitizeLevel.TextBox); PrintableCodeGenerated(null, postProcessCode); }
public void Test1() { var taCodeAllOptimizations = 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 = null, Operation = OpCode.Copy, Right = new IntConst(20), Result = new Var() }; var assgn4 = new Assign() { Left = new IntConst(20), Operation = OpCode.Mul, Right = new IntConst(3), Result = new Var() }; var assgn5 = new Assign() { Left = new IntConst(10), Operation = OpCode.Plus, Right = assgn3.Result, Result = new Var() }; taCodeAllOptimizations.AddNode(assgn1); taCodeAllOptimizations.AddNode(assgn2); taCodeAllOptimizations.AddNode(assgn3); taCodeAllOptimizations.AddNode(assgn4); taCodeAllOptimizations.AddNode(assgn5); /* * a = b * c = b - a -----> c = 0 * n = 20 * c = 20 * 3 -----> c = 60 * d = 10 + n -----> d = 30 */ var allOptimizations = new AllOptimizations(); allOptimizations.ApplyAllOptimizations(taCodeAllOptimizations); Assert.AreEqual(assgn2.Right, 0); Assert.AreEqual(assgn4.Right, 60); Assert.AreEqual(assgn5.Right, 30); Assert.True(true); }
public TransferFunction(TACode code) { _code = code; }
public Operations(TACode code) { upper = new HashSet <Guid>(code.CodeList.Where(x => x is Assign).Select(x => x.Label)); }
public NumeratedGraph(TACode code, IGraphNumerator numerator) : base(code) { Numerator = numerator; }
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("-----------------------------------------"); }