public bool Optimize(IterationAlgorithm <SemilatticeStreamValue> ita)
        {
            var bblocks     = ita.controlFlowGraph.SourceBasicBlocks.BasicBlockItems;
            var isOptimized = false;

            for (int i = 0; i < bblocks.Count; i++)
            {
                var m = ita.InOut.Out[bblocks[i]].ToDictionary(e => e.VarName);

                for (var it = bblocks[i].First; true; it = it.Next)
                {
                    var instuction = it.Value;

                    if (instuction is TacAssignmentNode tacInsruction)
                    {
                        if (Utility.Utility.IsVariable(tacInsruction.FirstOperand) &&
                            m.ContainsKey(tacInsruction.FirstOperand) &&
                            m[tacInsruction.FirstOperand].Value.TypeValue == SemilatticeValueEnum.CONST &&
                            tacInsruction.FirstOperand != m[tacInsruction.FirstOperand].Value.ConstValue
                            )
                        {
                            tacInsruction.FirstOperand = m[tacInsruction.FirstOperand].Value.ConstValue;
                            isOptimized = true;
                        }

                        if (tacInsruction.SecondOperand != null &&
                            Utility.Utility.IsVariable(tacInsruction.SecondOperand) &&
                            m.ContainsKey(tacInsruction.SecondOperand) &&
                            m[tacInsruction.SecondOperand].Value.TypeValue == SemilatticeValueEnum.CONST &&
                            tacInsruction.SecondOperand != m[tacInsruction.SecondOperand].Value.ConstValue
                            )
                        {
                            tacInsruction.SecondOperand = m[tacInsruction.SecondOperand].Value.ConstValue;
                            isOptimized = true;
                        }
                    }

                    if (it == bblocks[i].Last)
                    {
                        break;
                    }
                }
            }

            return(isOptimized);
        }
        public bool Optimize(IterationAlgorithm <TacNode> ita)
        {
            bool wasApplied = false;

            foreach (var basicBlock in ita.controlFlowGraph.SourceBasicBlocks)
            {
                var inData  = ita.InOut.In[basicBlock];
                var outData = ita.InOut.Out[basicBlock];
                DeadCodeOptimization dcOpt = new DeadCodeOptimization(InitializeVariables(basicBlock, outData));

                while (true)
                {
                    if (!dcOpt.Optimize(basicBlock))
                    {
                        break;
                    }
                    else
                    {
                        wasApplied = true;
                    }
                }
            }
            return(wasApplied);
        }
//        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);
        }
        public bool Optimize(IterationAlgorithm <TacNode> ita)
        {
            var wasApplied = false;

            foreach (var basicBlock in ita.controlFlowGraph.SourceBasicBlocks)
            {
                var isFirstBlock = false;

                var traversedNodesInBlock = new HashSet <TacAssignmentNode>();
                var inData  = ita.InOut.In[basicBlock];
                var outData = ita.InOut.Out[basicBlock];

                if (inData.Count == 0)
                {
                    inData       = outData;
                    isFirstBlock = true;
                }

                foreach (var line in basicBlock)
                {
                    if (!(line is TacAssignmentNode assignmentNode))
                    {
                        continue;
                    }
                    traversedNodesInBlock.Add(assignmentNode);

                    var firstOperand  = assignmentNode.FirstOperand;
                    var secondOperand = assignmentNode.SecondOperand;

                    if (firstOperand != null)
                    {
                        var tmpValue = Routine(inData, outData, firstOperand);
                        if (tmpValue != null)
                        {
                            var encounteredRedefinition = traversedNodesInBlock.FirstOrDefault(entry =>
                                                                                               string.Equals(tmpValue.LeftPartIdentifier,
                                                                                                             entry.LeftPartIdentifier)) != null;
                            if (isFirstBlock)
                            {
                                if (!encounteredRedefinition)
                                {
                                    continue;
                                }
                            }
                            else
                            {
                                if (encounteredRedefinition)
                                {
                                    continue;
                                }
                            }
                            assignmentNode.FirstOperand = tmpValue.FirstOperand;
                            wasApplied = true;
                        }
                    }

                    if (secondOperand != null)
                    {
                        var tmpValue = Routine(inData, outData, secondOperand);
                        if (tmpValue != null)
                        {
                            var encounteredRedefinition = traversedNodesInBlock.FirstOrDefault(entry =>
                                                                                               string.Equals(tmpValue.LeftPartIdentifier,
                                                                                                             entry.LeftPartIdentifier)) != null;
                            if (isFirstBlock)
                            {
                                if (!encounteredRedefinition)
                                {
                                    continue;
                                }
                            }
                            else
                            {
                                if (encounteredRedefinition)
                                {
                                    continue;
                                }
                            }
                            assignmentNode.SecondOperand = tmpValue.FirstOperand;
                            wasApplied = true;
                        }
                    }
                }
            }

            return(wasApplied);
        }