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);
        }
Exemplo n.º 2
0
        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);
        }