示例#1
0
        private void OptimizationInBlock(TacExpr expr, ThreeAddressCode block, string tmpName)
        {
            var taCode = block.TACodeLines.First;

            while (taCode != null)
            {
                var node = taCode.Value;
                if (node is TacAssignmentNode assign)
                {
                    TacExpr nodeExpr = new TacExpr(assign.FirstOperand, assign.Operation, assign.SecondOperand);
                    string  id       = assign.LeftPartIdentifier;
                    if (id == expr.FirstOperand || id == expr.SecondOperand)
                    {
                        block.TACodeLines.AddAfter(block.TACodeLines.Find(node), expr.CreateAssignNode(tmpName));
                    }
                    if (nodeExpr.Equals(expr) && id != tmpName)
                    {
                        assign.FirstOperand  = tmpName;
                        assign.Operation     = null;
                        assign.SecondOperand = null;
                    }
                }
                taCode = taCode.Next;
            }
        }
//        public bool Optimize(AvailableExpressionsITA ita)
        public bool Optimize(IterationAlgorithm <TacNode> ita)
        {
            bool isUsed = false;
            var  bb     = ita.controlFlowGraph.SourceBasicBlocks;
            Dictionary <ThreeAddressCode, HashSet <TacNode> > IN  = ita.InOut.In;
            Dictionary <ThreeAddressCode, HashSet <TacNode> > OUT = ita.InOut.Out;
            // переделываем IN OUT в нужный формат
            var IN_EXPR  = new Dictionary <ThreeAddressCode, HashSet <TacExpr> >();
            var OUT_EXPR = new Dictionary <ThreeAddressCode, HashSet <TacExpr> >();

            foreach (var block in bb.BasicBlockItems)
            {
                HashSet <TacExpr> inNode = TransformHashSetNodeToExpr(IN[block]);
                IN_EXPR.Add(block, inNode);
                HashSet <TacExpr> outNode = TransformHashSetNodeToExpr(OUT[block]);
                OUT_EXPR.Add(block, outNode);
            }
            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)
                    {
                        if (assign.Operation != null && assign.SecondOperand != null)
                        {
                            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];
                var codeLine = block.TACodeLines.First;
                foreach (var _expr in varsExprChange.Keys.ToArray())
                {
                    varsExprChange[_expr] = !IN_EXPR[block].Contains(_expr);
                }
                while (codeLine != null)
                {
                    var node = codeLine.Value;
                    if (node is TacAssignmentNode assign)
                    {
                        string  assignId     = assign.LeftPartIdentifier;
                        TacExpr expr         = new TacExpr(assign);
                        bool    isCommonExpr = false;
                        if (idsForExprDic.Keys.Contains(expr) && idsForExprDic[expr] == assignId)
                        {
                            isCommonExpr = true;
                        }
                        // если выражений больше 1 делаем оптимизацию
                        if (!isCommonExpr && tacExprCount.Keys.Contains(expr) && tacExprCount[expr] > 1)
                        {
                            isUsed = true;
                            if (!varsExprChange.Keys.Contains(expr))
                            {
                                varsExprChange.Add(expr, !IN_EXPR[block].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.ToArray())
                        {
                            // если выражение недоступно на выходе и присваивание его изменяет
                            if (_expr.FirstOperand == assignId || _expr.SecondOperand == assignId)
                            {
                                varsExprChange[_expr] = true;
                            }
                        }
                    }
                    codeLine = codeLine.Next;
                }
            }
            return(isUsed);
        }
示例#3
0
        public bool Optimize(ControlFlowGraph cfg)
        {
            bool isUsed = false;
            var  bb     = cfg.SourceBasicBlocks;

            for (int source = 0; source < bb.BasicBlockItems.Count(); source++)
            {
                var sourceBlock    = bb.BasicBlockItems[source];
                var sourceCodeLine = sourceBlock.TACodeLines.First;
                while (sourceCodeLine != null)
                {
                    var sourceNode = sourceCodeLine.Value;
                    if (sourceNode is TacAssignmentNode sourceAssign)
                    {
                        if (sourceAssign.SecondOperand == null)
                        {
                            break;
                        }
                        TacExpr sourceExpr = new TacExpr(sourceAssign.FirstOperand, sourceAssign.Operation, sourceAssign.SecondOperand);
                        for (int target = 0; target < bb.BasicBlockItems.Count(); target++)
                        {
                            var targetBlock    = bb.BasicBlockItems[target];
                            var targetCodeLine = targetBlock.TACodeLines.First;
                            while (targetCodeLine != null)
                            {
                                var targetNode = targetCodeLine.Value;
                                if (targetNode == sourceNode)
                                {
                                    break;
                                }
                                if (targetNode is TacAssignmentNode targetAssign)
                                {
                                    string  targetAssignId    = targetAssign.LeftPartIdentifier;
                                    bool    isNeedAdditionaly = targetAssignId == sourceExpr.FirstOperand || targetAssignId == sourceExpr.SecondOperand;
                                    TacExpr targetExpr        = new TacExpr(targetAssign.FirstOperand, targetAssign.Operation, targetAssign.SecondOperand);
                                    if (targetExpr.Equals(sourceExpr) || isNeedAdditionaly)
                                    {
                                        string tmpName = null;
                                        HashSet <ThreeAddressCode> hashSet = null;
                                        bool isIdVar = infoDictionary.ContainsKey(sourceExpr);
                                        if (!isIdVar)
                                        {
                                            tmpName = TmpNameManager.Instance.GenerateTmpVariableName();
                                            sourceBlock.TACodeLines.AddBefore(sourceBlock.TACodeLines.Find(sourceNode), sourceExpr.CreateAssignNode(tmpName));
                                            OptimizationInBlock(sourceExpr, sourceBlock, tmpName);
                                            hashSet = new HashSet <ThreeAddressCode>();
                                            hashSet.Add(sourceBlock);
                                            infoDictionary.Add(sourceExpr, new Tuple <string, HashSet <ThreeAddressCode> >(tmpName, hashSet));
                                        }
                                        else
                                        {
                                            if (!infoDictionary.ContainsKey(sourceExpr))
                                            {
                                                break;
                                            }
                                            var info = infoDictionary[sourceExpr];
                                            tmpName = info.Item1;
                                            hashSet = info.Item2;
                                        }
                                        if (sourceBlock == targetBlock)
                                        {
                                            break;
                                        }
                                        bool isOptim = hashSet.Contains(targetBlock);
                                        if (!isOptim)
                                        {
                                            isUsed = true;
                                            hashSet.Add(targetBlock);
                                            OptimizationInBlock(sourceExpr, targetBlock, tmpName);
                                            break;
                                        }
                                    }
                                }
                                targetCodeLine = targetCodeLine.Next;
                            }
                        }
                    }
                    sourceCodeLine = sourceCodeLine.Next;
                }
            }

            return(isUsed);
        }