public bool Optimize(ThreeAddressCode tac) { var isOptimized = false; var directAssignments = new Dictionary <string, string>(); var blocks = new BasicBlocks(); blocks.SplitTACode(tac); foreach (var block in blocks) { var currentNode = block.First; while (currentNode != null) { if (currentNode.Value is TacAssignmentNode assignmentNode) { if (assignmentNode.Operation == null) { if (directAssignments.ContainsKey(assignmentNode.LeftPartIdentifier)) { directAssignments.Remove(assignmentNode.LeftPartIdentifier); } if (!int.TryParse(assignmentNode.FirstOperand, out int firstOpValue)) { var id = assignmentNode.LeftPartIdentifier; var firstOp = assignmentNode.FirstOperand; directAssignments.Add(id, firstOp); } } if (directAssignments.ContainsKey(assignmentNode.FirstOperand)) { assignmentNode.FirstOperand = directAssignments[assignmentNode.FirstOperand]; isOptimized = true; } if (assignmentNode.SecondOperand != null && directAssignments.ContainsKey(assignmentNode.SecondOperand)) { assignmentNode.SecondOperand = directAssignments[assignmentNode.SecondOperand]; isOptimized = true; } if (directAssignments.ContainsKey(assignmentNode.LeftPartIdentifier) && assignmentNode.SecondOperand != null && assignmentNode.FirstOperand != null) { directAssignments.Remove(assignmentNode.LeftPartIdentifier); } } currentNode = currentNode.Next; } } return(isOptimized); }
public bool Optimize(ThreeAddressCode tac) { var blocks = new BasicBlocks(); blocks.SplitTACode(tac); var nodesByExpression = new Dictionary <string, LinkedListNode <TacNode> >(); var isOptimized = false; foreach (var block in blocks) { nodesByExpression.Clear(); var currentNode = block.First; while (currentNode != null) { if (currentNode.Value is TacAssignmentNode assignment && assignment.Operation != null && !int.TryParse(assignment.FirstOperand, out _) && !int.TryParse(assignment.SecondOperand, out _)) { var expression = RightPartToString(assignment); if (!nodesByExpression.ContainsKey(expression)) { nodesByExpression.Add(expression, currentNode); } else { var node = nodesByExpression[expression]; var assignmentNode = node.Value as TacAssignmentNode; if (IsPossibleToOptimize(node, currentNode, assignmentNode.FirstOperand, assignmentNode.SecondOperand)) { assignment.FirstOperand = assignmentNode.LeftPartIdentifier; assignment.Operation = null; assignment.SecondOperand = null; isOptimized = true; } else { nodesByExpression[expression] = currentNode; } } } currentNode = currentNode.Next; } } return(isOptimized); }
public bool Optimize(BasicBlocks bb, IterationAlgorithm <TacNode> ita) { bool isUsed = false; Dictionary <ThreeAddressCode, HashSet <TacNode> > IN = ita.InOut.In; Dictionary <ThreeAddressCode, HashSet <TacNode> > OUT = ita.InOut.Out; Dictionary <TacExpr, int> tacExprCount = new Dictionary <TacExpr, int>(); Dictionary <TacExpr, bool> varsExprChange = new Dictionary <TacExpr, bool>(); // ищем какие выражения нужно оптимизировать foreach (var block in bb.BasicBlockItems) { foreach (TacNode node in block.TACodeLines) { if (node is TacAssignmentNode assign) { TacExpr expr = new TacExpr(assign); if (!tacExprCount.Keys.Contains(expr)) { tacExprCount.Add(expr, 1); } else { tacExprCount[expr] += 1; } } } } // проводим оптимизацию for (int blockInd = 0; blockInd < bb.BasicBlockItems.Count(); blockInd++) { var block = bb.BasicBlockItems[blockInd]; HashSet <TacExpr> inNode = TransformHashSetNodeToExpr(IN[block]); HashSet <TacExpr> outNode = TransformHashSetNodeToExpr(OUT[block]); var codeLine = block.TACodeLines.First; while (codeLine != null) { var node = codeLine.Value; if (node is TacAssignmentNode assign) { string assignId = assign.LeftPartIdentifier; TacExpr expr = new TacExpr(assign); // если выражений больше 1 делаем оптимизацию if (tacExprCount[expr] > 1) { DictionarySetOrAdd(varsExprChange, expr, !inNode.Contains(expr)); // если это первая замена общего выражения if (!idsForExprDic.Keys.Contains(expr)) { // создаём переменную для общего выражения string idName = TmpNameManager.Instance.GenerateTmpVariableName(); idsForExprDic.Add(expr, idName); block.TACodeLines.AddBefore(block.TACodeLines.Find(node), expr.CreateAssignNode(idName)); AssignRightPartVarReplace(assign, idName); varsExprChange[expr] = false; } else { string idName = idsForExprDic[expr]; // если это не замена общего выражения if (assignId != idName) { AssignRightPartVarReplace(assign, idName); } // если выражение недоступно на входе if (varsExprChange[expr]) { block.TACodeLines.AddBefore(block.TACodeLines.Find(node), expr.CreateAssignNode(idName)); varsExprChange[expr] = false; } } } // для всех оптимизируемых выражений foreach (var _expr in varsExprChange.Keys) { // если выражение недоступно на выходе и присваивание его изменяет if (!outNode.Contains(_expr) && (_expr.FirstOperand == assignId || _expr.SecondOperand == assignId)) { varsExprChange[_expr] = true; } } } } } return(isUsed); }