/// <summary> /// Применяет к графу <paramref name="graph"/> удаление мертвых переменных на основе /// информации о множествах IN и OUT для блоков из <paramref name="InOut"/>. /// Возвращает новый граф с выполненной на нем оптимизацией без изменения исходного графа. /// </summary> /// <param name="InOut"></param> /// <param name="graph"></param> /// <returns></returns> public CFG DeadOrAliveOnGraph(List <HashSet <string> > OutBlocks, CFG graph) { IsApplyed = false; var resGraph = new ControlFlowGraph.ControlFlowGraph( new List <LinkedList <Visitors.ThreeCode> >(graph.blocks)); if (OutBlocks.Count != resGraph.blocks.Count) { throw new ArgumentException("The number of elements in the sets OUT, graph.blocks must be equal"); } for (int i = resGraph.blocks.Count - 1; i >= 0; i--) { var variables = new Dictionary <string, bool>(); foreach (var ъуъ in OutBlocks[i]) { variables[ъуъ] = true; } var Optimizer = new DeadOrAliveOptimizationAdapter(); resGraph.blocks[i] = Optimizer.DeleteDeadVariables(resGraph.blocks[i], variables); IsApplyed = IsApplyed || Optimizer.Applyed(); } return(resGraph); }
public DefUseBlocks(CFG graph) { DefBs = new List <HashSet <string> >(); UseBs = new List <HashSet <string> >(); Graph = graph; MakeSets(); }
public void Apply(ref List <LinkedList <ThreeCode> > res) { // Добавление фиктивных узлов var entry = new LinkedList <ThreeCode>(); entry.AddFirst(new ThreeCode("entry", "", ThreeOperator.None, null, null)); var exit = new LinkedList <ThreeCode>(); exit.AddFirst(new ThreeCode("exit", "", ThreeOperator.None, null, null)); res.Insert(0, entry); res.Add(exit); // построение CFG по блокам CFG controlFlowGraph = new CFG(res); // вычисление множеств Def и Use для всего графа потоков данных var DefUse = new DefUseBlocks(controlFlowGraph); // вычисление множеств IN, OUT на основе DefUse var Out = new InOutActiveVariables(DefUse, controlFlowGraph).OutBlocks; // Выполнение оптимизации controlFlowGraph = ControlFlowOptimisations.DeadOrAliveOnGraph(Out, controlFlowGraph); // Удаление фиктивных узлов res = controlFlowGraph.blocks; res.RemoveAt(0); res.RemoveAt(res.Count - 1); }
public ConstantPropagationItA(CFG graph) { Graph = graph; IN = new List <Dictionary <string, string> >(); OUT = new List <Dictionary <string, string> >(); }
public static CFG DeadOrAliveOptimization(List <LinkedList <ThreeCode> > blocks) { // построение CFG по блокам CFG controlFlowGraph = new CFG(blocks); // вычисление множеств Def и Use для всего графа потоков данных var DefUse = new DefUseBlocks(controlFlowGraph); // создание информации о блоках var blocksInfo = new List <BlockInfo <string> >(); for (int i = 0; i < DefUse.DefBs.Count; i++) { blocksInfo.Add(new BlockInfo <string>(DefUse.DefBs[i], DefUse.UseBs[i])); } // оператор сбора для анализа активных переменных Func <List <BlockInfo <string> >, CFG, int, BlockInfo <string> > meetOperator = (blocksInfos, graph, index) => { var successorIndexes = graph.cfg.GetOutputNodes(index); var resInfo = new BlockInfo <string>(blocksInfos[index]); foreach (var i in successorIndexes) { resInfo.OUT.UnionWith(blocksInfos[i].IN); } return(resInfo); }; // делегат передаточной функции для анализа активных переменных Func <BlockInfo <string>, BlockInfo <string> > tFunc = (blockInfo) => { blockInfo.IN = new HashSet <string>(); blockInfo.IN.UnionWith(blockInfo.OUT); blockInfo.IN.ExceptWith(blockInfo.HelpFirst); blockInfo.IN.UnionWith(blockInfo.HelpSecond); return(blockInfo); }; var transferFunction = new GenericTransferFunction.TransferFunction <BlockInfo <string> >(tFunc); // создание объекта итерационного алгоритма var iterativeAlgorithm = new IterativeAlgorithm <string>(blocksInfo, controlFlowGraph, meetOperator, false, new HashSet <string>(), new HashSet <string>(), transferFunction); // выполнение алгоритма iterativeAlgorithm.Perform(); controlFlowGraph = ControlFlowOptimisations.DeadOrAliveOnGraph( iterativeAlgorithm.GetOUTs(), controlFlowGraph); return(controlFlowGraph); }
public void IterativeAlgorithm(List <LinkedList <ThreeCode> > blocks) { var bb = new LinkedList <ThreeCode>(); bb.AddLast(new ThreeCode("entry", "", ThreeOperator.None, null, null)); var bs = blocks.ToList(); // добавление пустого входного блока - необходимо для корректной работы ит. алгоритма bs.Insert(0, bb); // построение CFG по блокам controlFlowGraph = new CFG(bs); // создание информации о блоках var blocksInfo = new List <BlockInfo <Expr> >(); for (int i = 0; i < bs.Count; i++) { blocksInfo.Add(new BlockInfo <Expr>(bs[i])); } // оператор сбора для доступных выражений Func <List <BlockInfo <Expr> >, CFG, int, BlockInfo <Expr> > meetOperator = (blocksInfos, graph, index) => { var inputIndexes = graph.cfg.GetInputNodes(index); var resInfo = new BlockInfo <Expr>(blocksInfos[index]); resInfo.IN = resInfo.OUT; // универсальное множество foreach (var i in inputIndexes) { resInfo.IN.IntersectWith(blocksInfos[i].OUT); } return(resInfo); }; var transferFunction = AvaliableExprsAdaptor.TransferFunction(); var U = new HashSet <Expr>(blocks.Select(b => b.Where(c => AvaliableExprs.IsDefinition(c.operation)) .Select(c => (c.arg1, c.operation, c.arg2))) .Aggregate((s1, s2) => s1.Union(s2))); // создание объекта итерационного алгоритма var iterativeAlgorithm = new IterativeAlgorithm <Expr>(blocksInfo, controlFlowGraph, meetOperator, true, new HashSet <Expr>(), U, transferFunction); // выполнение алгоритма iterativeAlgorithm.Perform(); Ins = iterativeAlgorithm.GetINs(); Outs = iterativeAlgorithm.GetOUTs(); }
public void Apply(ref List <LinkedList <ThreeCode> > res) { _Applied = false; var old = res.Select(b => new LinkedList <string>(b.Select(c => c.ToString()))).ToList(); var constPropOptimizer = new ConstantPropagationOptimizer(); CFG cfg = constPropOptimizer.ApplyOptimization(res); res = cfg.blocks; for (int i = 0; i < old.Count; ++i) { for (int j = 0; j < old[i].Count; ++j) { var it1 = old[i].ElementAt(j); var it2 = res[i].ElementAt(j); if (!it1.ToString().Equals(it2.ToString())) { _Applied = true; return; } } } }
public void Apply(ref List <LinkedList <ThreeCode> > res) { var old = res.Select(b => new LinkedList <string>(b.Select(c => c.ToString()))).ToList(); var availableExprsOptimizer = new AvailableExprsOptimizer(); CFG cfg = availableExprsOptimizer.ApplyOptimization(res); res = cfg.blocks; for (int i = 0; i < old.Count; ++i) { var it1 = old[i].First; var it2 = res[i].First; for (int j = 0; j < old[i].Count; ++j) { if (it1.Value.ToString() != it2.Value.ToString()) { Applied = true; return; } it1 = it1.Next; it2 = it2.Next; } } }
public void IterativeAlgorithm(List <LinkedList <ThreeCode> > blocks) { // построение CFG по блокам controlFlowGraph = new CFG(blocks.ToList()); // создание информации о блоках var blocksInfo = new List <BlockInfo <ThreeCode> >(); for (int i = 0; i < blocks.Count; i++) { blocksInfo.Add(new BlockInfo <ThreeCode>(blocks[i])); } // оператор сбора в задаче о распространении констант Func <List <BlockInfo <ThreeCode> >, CFG, int, BlockInfo <ThreeCode> > meetOperator = (blocksInfos, graph, index) => { var inputIndexes = graph.cfg.GetInputNodes(index); var resInfo = new BlockInfo <ThreeCode>(blocksInfos[index]); foreach (var i in inputIndexes) { resInfo.IN.UnionWith(blocksInfos[i].OUT); } return(resInfo); }; var transferFunction = new ReachingDefsAdaptor(controlFlowGraph).TransferFunction(); // создание объекта итерационного алгоритма var iterativeAlgorithm = new IterativeAlgorithm <ThreeCode>(blocksInfo, controlFlowGraph, meetOperator, true, new HashSet <ThreeCode>(), new HashSet <ThreeCode>(), transferFunction); // выполнение алгоритма iterativeAlgorithm.Perform(); Ins = iterativeAlgorithm.GetINs(); Outs = iterativeAlgorithm.GetOUTs(); }
public void IterativeAlgorithm(List <LinkedList <ThreeCode> > blocks) { // построение CFG по блокам controlFlowGraph = new CFG(blocks.ToList()); // создание информации о блоках var blocksInfo = new List <ConstPropBlockInfo>(); var m = new Dictionary <string, ConstPropSemilatticeEl>(); for (int i = 0; i < blocks.Count; i++) { foreach (var c in blocks[i].Where(com => com.operation != ThreeOperator.Goto && com.operation != ThreeOperator.IfGoto)) { string[] vars = new string[] { c.result , (c.arg1 as ThreeAddressStringValue)?.Value , (c.arg2 as ThreeAddressStringValue)?.Value }; foreach (var v in vars) { if (v != null && v != "" && !m.ContainsKey(v)) { m[v] = new ConstPropSemilatticeEl(ValConstType.Undef); } } } } for (int i = 0; i < blocks.Count; i++) { blocksInfo.Add(new ConstPropBlockInfo(blocks[i])); } // оператор сбора в задаче о распространении констант Func <List <ConstPropBlockInfo>, CFG, int, ConstPropBlockInfo> meetOperator = (blocksInfos, graph, index) => { var inputIndexes = graph.cfg.GetInputNodes(index); var resInfo = new ConstPropBlockInfo(blocksInfos[index]); foreach (var i in inputIndexes) { var resIn = resInfo.IN.ToDictionary(e => e.Key); foreach (var Out in blocksInfos[i].OUT) { if (resIn[Out.Key].Value.Constantness == ValConstType.Undef) { resIn[Out.Key] = new ConstPropKeyValue(Out.Key, Out.Value); } else if (resIn[Out.Key].Value.Constantness == ValConstType.NAC || Out.Value.Constantness == ValConstType.NAC || (resIn[Out.Key].Value.Constantness == ValConstType.Const && Out.Value.Constantness == ValConstType.Const && resIn[Out.Key].Value.Value != Out.Value.Value)) { resIn[Out.Key] = new ConstPropKeyValue(Out.Key, new ConstPropSemilatticeEl(ValConstType.NAC)); } } resInfo.IN = new HashSet <ConstPropKeyValue>(resIn.Values); } return(resInfo); }; var transferFunction = TransferFunction(); // создание объекта итерационного алгоритма var iterativeAlgorithm = new IterativeAlgorithm <ConstPropKeyValue>(blocksInfo, controlFlowGraph, meetOperator, true, new HashSet <ConstPropKeyValue>(m), new HashSet <ConstPropKeyValue>(m), transferFunction); // выполнение алгоритма iterativeAlgorithm.Perform(); Ins = iterativeAlgorithm.GetINs(); }
public ReachingDefsTransferFunction(CFG cfg) => this.cfg = cfg;
public ReachingDefsAdaptor(CFG cfg) => tf = new ReachingDefsTransferFunction(cfg);
private void UpdateTab(Modes m, TextBox txt, PictureBox box, Panel panel) { if (FileName.Length == 0) { txt.Text = "File is not set"; return; } try { if (m == Modes.AfterGraph || m == Modes.BeforeGraph) { panel.Visible = true; txt.Visible = false; } else { panel.Visible = false; txt.Visible = true; } string tt = System.IO.File.ReadAllText(FileName); if (m == Modes.Text) { txt.Text = tt; return; } SimpleScanner.Scanner scan = new SimpleScanner.Scanner(); scan.SetSource(tt, 0); SimpleParser.Parser pars = new SimpleParser.Parser(scan); var b = pars.Parse(); if (!b) { txt.Text = "Ошибка парсинга"; return; } var r = pars.root; SimpleLang.Visitors.FillParentVisitor parVisitor = new SimpleLang.Visitors.FillParentVisitor(); r.Visit(parVisitor); SimpleLang.Visitors.ThreeAddressCodeVisitor threeCodeVisitor = new SimpleLang.Visitors.ThreeAddressCodeVisitor(); r.Visit(threeCodeVisitor); if (m == Modes.BeforeThreeCode) { txt.Text = SimpleLang.Visitors.ThreeAddressCodeVisitor.ToString(threeCodeVisitor.GetCode()); Console.WriteLine(txt.Text); return; } if (m == Modes.BeforeRun) { SimpleLang.Compiler.ILCodeGenerator gen = new SimpleLang.Compiler.ILCodeGenerator(); gen.Generate(threeCodeVisitor.GetCode()); List <long> datas = new List <long>(); List <long> datas2 = new List <long>(); int count_run = Int32.Parse(textBox3.Text); string res = ""; for (int i = 0; i < count_run; i++) { var timer = System.Diagnostics.Stopwatch.StartNew(); res = gen.Execute(); timer.Stop(); datas.Add(timer.ElapsedMilliseconds); datas2.Add(timer.ElapsedTicks); } res = res + Environment.NewLine + Environment.NewLine + "Executed avg: " + (datas.Min()).ToString() + " ms" + " or " + (datas2.Min()).ToString() + " ticks" + Environment.NewLine; for (int i = 0; i < datas.Count; i++) { res = res + i.ToString() + ": " + datas[i].ToString() + " ms or " + datas2[i].ToString() + " ticks" + Environment.NewLine; } txt.Text = res; return; } if (m == Modes.BeforeBlocks) { var blocks = new SimpleLang.Block.Block(threeCodeVisitor).GenerateBlocks(); txt.Text = SimpleLang.Visitors.ThreeAddressCodeVisitor.ToString(blocks); return; } if (m == Modes.BeforeMass) { var blocks = new SimpleLang.Block.Block(threeCodeVisitor).GenerateBlocks(); DrawMass(blocks, txt); return; } if (m == Modes.BeforeGraph) { var blocks = new SimpleLang.Block.Block(threeCodeVisitor).GenerateBlocks(); SimpleLang.ControlFlowGraph.ControlFlowGraph gra = new SimpleLang.ControlFlowGraph.ControlFlowGraph(blocks); DrawCFG(box, gra.cfg, blocks, panel); return; } SimpleLang.Visitors.AutoApplyVisitor optAst = GetASTOptimizer(); optAst.Apply(r); if (m == Modes.ASTOpt) { SimpleLang.Visitors.PrettyPrintVisitor vis = new SimpleLang.Visitors.PrettyPrintVisitor(); r.Visit(vis); txt.Text = vis.Text; return; } threeCodeVisitor = new SimpleLang.Visitors.ThreeAddressCodeVisitor(); r.Visit(threeCodeVisitor); var opt = GetOptimiser(); var outcode = opt.Apply(threeCodeVisitor); if (m == Modes.AfterMass) { DrawMass(outcode, txt); return; } if (m == Modes.AfterBlocks) { txt.Text = SimpleLang.Visitors.ThreeAddressCodeVisitor.ToString(outcode); return; } if (m == Modes.AfterGraph) { SimpleLang.ControlFlowGraph.ControlFlowGraph gra = new SimpleLang.ControlFlowGraph.ControlFlowGraph(outcode); DrawCFG(box, gra.cfg, outcode, panel); return; } if (m == Modes.AfterTbreeCode) { System.Collections.Generic.LinkedList <SimpleLang.Visitors.ThreeCode> res = new System.Collections.Generic.LinkedList <SimpleLang.Visitors.ThreeCode>(); foreach (var block in outcode) { foreach (SimpleLang.Visitors.ThreeCode code in block) { res.AddLast(code); } } txt.Text = SimpleLang.Visitors.ThreeAddressCodeVisitor.ToString(res); Console.WriteLine(txt.Text); return; } if (m == Modes.AfterRun) { System.Collections.Generic.LinkedList <SimpleLang.Visitors.ThreeCode> res = new System.Collections.Generic.LinkedList <SimpleLang.Visitors.ThreeCode>(); foreach (var block in outcode) { foreach (SimpleLang.Visitors.ThreeCode code in block) { res.AddLast(code); } } SimpleLang.Compiler.ILCodeGenerator gen = new SimpleLang.Compiler.ILCodeGenerator(); gen.Generate(res); List <long> datas = new List <long>(); List <long> datas2 = new List <long>(); int count_run = Int32.Parse(textBox3.Text); string re2 = ""; for (int i = 0; i < count_run; i++) { var timer = System.Diagnostics.Stopwatch.StartNew(); re2 = gen.Execute(); timer.Stop(); datas.Add(timer.ElapsedMilliseconds); datas2.Add(timer.ElapsedTicks); } re2 = re2 + Environment.NewLine + Environment.NewLine + "Executed avg: " + (datas.Min()).ToString() + " ms" + " or " + (datas2.Min()).ToString() + " ticks" + Environment.NewLine; for (int i = 0; i < datas.Count; i++) { re2 = re2 + i.ToString() + ": " + datas[i].ToString() + " ms or " + datas2[i].ToString() + " ticks" + Environment.NewLine; } txt.Text = re2; return; } txt.Text = "Is not implemented"; } catch (Exception e) { panel.Visible = false; txt.Visible = true; txt.Text = e.ToString(); } }
private void DrawMass(List <LinkedList <SimpleLang.Visitors.ThreeCode> > code, TextBox txt) { if (radioButton1.Checked) { SimpleLang.ControlFlowGraph.ControlFlowGraph gra = new SimpleLang.ControlFlowGraph.ControlFlowGraph(code); SimpleLang.Dominators.DominatorsFinder finder = new SimpleLang.Dominators.DominatorsFinder(gra); finder.Find(); txt.Text = finder.ToString(); } if (radioButton2.Checked) { SimpleLang.ThreeCodeOptimisations.ReachingDefsAnalysis defs = new SimpleLang.ThreeCodeOptimisations.ReachingDefsAnalysis(); defs.IterativeAlgorithm(code); txt.Text = defs.GetOutput(); } if (radioButton3.Checked) { var tmp = System.Console.Out; System.IO.MemoryStream stre = new System.IO.MemoryStream(); System.IO.TextWriter wr = new System.IO.StreamWriter(stre); Console.SetOut(wr); SimpleLang.ControlFlowGraph.ControlFlowGraph gra = new SimpleLang.ControlFlowGraph.ControlFlowGraph(code); SimpleLang.DetectReversibleEdges find = new SimpleLang.DetectReversibleEdges(gra); find.PrintIsReverseDic(); Console.SetOut(tmp); wr.Flush(); stre.Flush(); string res = Encoding.UTF8.GetString(stre.ToArray()); txt.Text = res; } if (radioButton4.Checked) { var tmp = System.Console.Out; System.IO.MemoryStream stre = new System.IO.MemoryStream(); System.IO.TextWriter wr = new System.IO.StreamWriter(stre); Console.SetOut(wr); SimpleLang.ControlFlowGraph.ControlFlowGraph gra = new SimpleLang.ControlFlowGraph.ControlFlowGraph(code); SimpleLang.DetectReversibleEdges find = new SimpleLang.DetectReversibleEdges(gra); find.PrintisReducible(); Console.SetOut(tmp); wr.Flush(); stre.Flush(); string res = Encoding.UTF8.GetString(stre.ToArray()); txt.Text = res; } if (radioButton5.Checked) { SimpleLang.ControlFlowGraph.ControlFlowGraph gra = new SimpleLang.ControlFlowGraph.ControlFlowGraph(code); SimpleLang.ThreeCodeOptimisations.DefUseBlocks def = new SimpleLang.ThreeCodeOptimisations.DefUseBlocks(gra); var d1 = def.DefBs; var d2 = def.UseBs; string res = ""; if (d1.Count == d2.Count) { for (int i = 0; i < d1.Count; i++) { res = res + "----------------------" + Environment.NewLine + "Block " + i.ToString() + Environment.NewLine; var a1 = d1[i]; var a2 = d2[i]; res = res + "\tDefB:" + Environment.NewLine; foreach (string t in a1) { res = res + "\t\t" + t + Environment.NewLine; } res = res + "\tUseB:" + Environment.NewLine; foreach (string t in a2) { res = res + "\t\t" + t + Environment.NewLine; } } } txt.Text = res; } if (radioButton6.Checked) { var tmp = System.Console.Out; System.IO.MemoryStream stre = new System.IO.MemoryStream(); System.IO.TextWriter wr = new System.IO.StreamWriter(stre); Console.SetOut(wr); SimpleLang.ControlFlowGraph.ControlFlowGraph gra = new SimpleLang.ControlFlowGraph.ControlFlowGraph(code); SpanTree span = new SpanTree(gra); span.buildSpanTree(); span.writeAllSpanTreeEdges(); Console.WriteLine(); Console.WriteLine("\t\tTypes:"); span.writeAllEdgesWithTypes(); Console.SetOut(tmp); wr.Flush(); stre.Flush(); string res = Encoding.UTF8.GetString(stre.ToArray()); txt.Text = res; } if (radioButton7.Checked) { SimpleLang.ControlFlowGraph.ControlFlowGraph gra = new SimpleLang.ControlFlowGraph.ControlFlowGraph(code); SimpleLang.ThreeCodeOptimisations.DefUseBlocks def = new SimpleLang.ThreeCodeOptimisations.DefUseBlocks(gra); var ou = new SimpleLang.ThreeCodeOptimisations.InOutActiveVariables(def, gra); List <HashSet <string> > _in = ou.InBlocks; List <HashSet <string> > _out = ou.OutBlocks; string res = ""; for (int i = 0; i < _in.Count; i++) { res = res + "----------------------" + Environment.NewLine + "Block " + i.ToString() + Environment.NewLine; res = res + "\tIN:" + Environment.NewLine; foreach (string t in _in[i]) { res = res + "\t\t" + t + Environment.NewLine; } res = res + "\tOUT:" + Environment.NewLine; foreach (string t in _out[i]) { res = res + "\t\t" + t + Environment.NewLine; } } txt.Text = res; } }