private bool TryOptimize(BaseBlock bblock, ExprSet input, IEnumerable <BaseBlock> prev) { for (int i = 0; i < bblock.Code.Count; ++i) { var line = bblock.Code[i]; if (ThreeAddrOpType.IsDefinition(line.OpType) && line.OpType != ThreeAddrOpType.Assign && line.OpType != ThreeAddrOpType.Read) { var expr = (line.LeftOp, line.OpType, line.RightOp); if (input.Contains(expr)) { if (TryExtract(prev, expr)) { line.RightOp = "tt" + _tempcount.ToString(); _tempcount++; line.OpType = ThreeAddrOpType.Assign; line.LeftOp = null; return(true); } } } input = TransferByLine(input, line); } return(false); }
public static ExprSet TransferByGenAndKiller(ExprSet X, ExprSet gen, KillerSet kill) { if (X == null) { return(gen); } return(new ExprSet(X.Where(e => !kill.Contains(e.Item1.ToString()) && !kill.Contains(e.Item3?.ToString())).Union(gen))); }
public (List <ExprSet>, List <ExprSet>) GenerateInputOutputAvaliableExpr() { var In = new List <ExprSet>(); var Out = new List <ExprSet>(); var startToId = GetStartToId(_bblocks); for (int i = 0; i < _bblocks.Count(); ++i) { In.Add(null); Out.Add(new ExprSet()); if (i > 0) { Out[i] = new ExprSet(_genExprByStart.SelectMany(kv => kv.Value.ToList())); } } bool change = true; while (change) { change = false; for (int i = 0; i < _bblocks.Count(); ++i) { var st = _bblocks[i].StartLabel; In[i] = null; foreach (var p in Prev[st]) { if (In[i] == null) { In[i] = new ExprSet(Out[startToId[p]]); } else { In[i].IntersectWith(Out[startToId[p]]); } } int sz = Out[i].Count; Out[i] = AvaliableExprs.TransferByGenAndKiller(In[i], _genExprByStart[st], _defByStart[st]); change |= sz != Out[i].Count; } } return(In, Out); }
public static ExprSet GetGenExprSet(LinkedList <ThreeCode> bblock) { var ret = new ExprSet(); foreach (var line in bblock) { if (line.operation == ThreeOperator.Goto || line.operation == ThreeOperator.IfGoto || line.operation == ThreeOperator.Println || line.operation == ThreeOperator.None) { continue; } ret.RemoveWhere(x => x.Item1.ToString() == line.result || x.Item3.ToString() == line.result); if (line.operation == ThreeOperator.Plus || line.operation == ThreeOperator.Mult || line.operation == ThreeOperator.Minus || line.operation == ThreeOperator.Logic_or || line.operation == ThreeOperator.Logic_not || line.operation == ThreeOperator.Logic_neq || line.operation == ThreeOperator.Logic_less || line.operation == ThreeOperator.Logic_leq || line.operation == ThreeOperator.Logic_greater || line.operation == ThreeOperator.Logic_geq || line.operation == ThreeOperator.Logic_equal || line.operation == ThreeOperator.Logic_and || line.operation == ThreeOperator.Div) { ret.Add(new Expr(line.arg1, line.operation, line.arg2)); } } return(ret); }
//Фукнция, возвращающая множества выражений, достпуных на входе и на выходе public (List <ExprSet>, List <ExprSet>) GenerateInputOutputAvaliableExpr(List <LinkedList <ThreeCode> > _bblocks) { //Множество выражений, доступных на входе IN[B] для всех ББл B var In = new List <ExprSet>(); //Множество выражений, доступных на выходе OUT[B] для всех ББл B var Out = new List <ExprSet>(); //Экземпляр класса AvaliableExprs для некоторых методов var ae = new AvaliableExprs(); //e_genB Dictionary <int, ExprSet> _genExprByStart = new Dictionary <int, ExprSet>(); Dictionary <int, List <HashSet <ThreeCode> > > _defByStart = new Dictionary <int, List <HashSet <ThreeCode> > >(); for (int i = 0; i < _bblocks.Count; i++) { _genExprByStart[i] = AvaliableExprs.GetGenExprSet(_bblocks[i]); } for (int i = 0; i < _bblocks.Count; i++) { _defByStart[i] = InstructionGens(_bblocks[i]); } for (int i = 0; i < _bblocks.Count(); ++i) { In.Add(null); Out.Add(new ExprSet()); if (i > 0) { Out[i] = new ExprSet(_genExprByStart.SelectMany(kv => kv.Value.ToList())); } } //Внесены ли изменения в Out bool change = true; while (change) { change = false; //Каждый ББ отличный от входного for (int B = 1; B < _bblocks.Count(); ++B) { In[B] = null; var cfg = new ControlFlowGraph(_bblocks); var inputIndexes = cfg.cfg.GetInputNodes(B); foreach (var P in inputIndexes) { //Проверяем, что коллекция еще не создана if (In[B] == null) { In[B] = new ExprSet(Out[P]); } else { In[B].IntersectWith(Out[P]); } } int sz = Out[B].Count; Out[B] = AvaliableExprs.TransferByGenAndKiller(In[B], AvaliableExprs.GetGenExprSet(_bblocks[B]), AvaliableExprs.GetKillerSet(_bblocks[B])); change |= sz != Out[B].Count; } } return(In, Out); }