예제 #1
0
        public static ControlFlowGraph LiveVariableDeleteDeadCode(ControlFlowGraph cfg)
        {
            var newInstructions = new List <Instruction>();

            var activeVariable    = new LiveVariableAnalysis();
            var resActiveVariable = activeVariable.Execute(cfg);

            foreach (var x in cfg.GetCurrentBasicBlocks().Take(cfg.GetCurrentBasicBlocks().Count - 1).Skip(1))
            {
                var instructionsTemp = x.GetInstructions();
                if (resActiveVariable.ContainsKey(x))
                {
                    var InOutTemp = resActiveVariable[x];
                    foreach (var i in instructionsTemp)
                    {
                        if (!InOutTemp.Out.Contains(i.Result) && i.Operation == "assign" && i.Argument1 != i.Result)
                        {
                            if (i.Label != "")
                            {
                                newInstructions.Add(new Instruction(i.Label, "noop", "", "", ""));
                            }
                        }
                        else
                        {
                            newInstructions.Add(i);
                        }
                    }
                }
            }
            return(new ControlFlowGraph(newInstructions));
        }
        public void DeleteDeadCode(ControlFlowGraph graph)
        {
            var usedVars = CreateUsedVarsSets(graph);
            var info     = new ReachingDefinitions().Execute(graph);

            var usedDefinitions = new HashSet <Instruction>(
                info[graph.GetCurrentBasicBlocks().Last()].In,
                new InstructionComparer());

            var possibleOperationTypes = new[] { "assign", "input", "PLUS" };

            var wasChanged = true;

            while (wasChanged)
            {
                wasChanged = false;

                foreach (var block in graph.GetCurrentBasicBlocks())
                {
                    var deadDefinitions = info[block].In.Except(info[block].Out);
                    foreach (var oldDef in deadDefinitions)
                    {
                        var variable = oldDef.Result;

                        // find first assign in current block that rewrites variable
                        var newDefIndex = block.GetInstructions()
                                          .Select((t, i) => new { Instruction = t, Index = i })
                                          .First(t => possibleOperationTypes.Contains(t.Instruction.Operation) && t.Instruction.Result == variable)
                                          .Index;

                        var blockWithOldDef = graph.GetCurrentBasicBlocks()
                                              .Single(z => z.GetInstructions().Any(t => t == oldDef));
                        var oldDefIndex = blockWithOldDef.GetInstructions()
                                          .Select((t, i) => new { Instruction = t, Index = i })
                                          .Single(t => t.Instruction == oldDef)
                                          .Index;

                        if (usedDefinitions.Contains(oldDef) ||
                            IsUsedInCurrentBlock(block, variable, newDefIndex) ||
                            IsUsedInOriginalBlock(blockWithOldDef, variable, oldDefIndex) ||
                            IsUsedInOtherBlocks(graph, blockWithOldDef, oldDef, usedVars, info))
                        {
                            usedDefinitions.Add(oldDef);
                            continue;
                        }

                        // remove useless definition
                        blockWithOldDef.RemoveInstructionByIndex(oldDefIndex);
                        if (!string.IsNullOrEmpty(oldDef.Label))
                        {
                            blockWithOldDef.InsertInstruction(oldDefIndex, new Instruction(oldDef.Label, "noop", null, null, null));
                        }
                        info       = new ReachingDefinitions().Execute(graph);
                        wasChanged = true;
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Принимает Граф потока данных и по нему ищет все естественные циклы
        /// </summary>
        /// <param name="cfg">Граф потока управления</param>
        /// <returns>
        /// Вернет все натуральные циклы
        /// </returns>
        public static IReadOnlyList <IReadOnlyList <BasicBlock> > GetAllNaturalLoops(ControlFlowGraph cfg)
        {
            if (cfg.IsReducibleGraph())
            {
                var natLoops     = new List <List <BasicBlock> >();
                var ForwardEdges = cfg.GetCurrentBasicBlocks();

                foreach (var(From, To) in cfg.GetBackEdges())
                {
                    if (cfg.VertexOf(To) > 0)
                    {
                        var tmp = new List <BasicBlock>();
                        for (var i = cfg.VertexOf(To); i < cfg.VertexOf(From) + 1; i++)
                        {
                            if (!tmp.Contains(ForwardEdges[i]))
                            {
                                tmp.Add(ForwardEdges[i]);
                            }
                        }

                        natLoops.Add(tmp);
                    }
                }

                return(natLoops.Where(loop => IsNaturalLoop(loop, cfg)).ToList());
            }
            else
            {
                Console.WriteLine("Граф не приводим");
                return(new List <List <BasicBlock> >());
            }
        }
예제 #4
0
        public ReachingTransferFunc(ControlFlowGraph g)
        {
            var basicBlocks = g.GetCurrentBasicBlocks();

            GetDefs(basicBlocks);
            GetGenKill(basicBlocks);
        }
        private Dictionary <BasicBlock, HashSet <string> > CreateUsedVarsSets(ControlFlowGraph graph)
        {
            var result = new Dictionary <BasicBlock, HashSet <string> >();

            foreach (var block in graph.GetCurrentBasicBlocks())
            {
                result[block] = new HashSet <string>();
                foreach (var instruction in block.GetInstructions())
                {
                    if (IsVariable(instruction.Argument1))
                    {
                        result[block].Add(instruction.Argument1);
                    }
                    if (IsVariable(instruction.Argument2))
                    {
                        result[block].Add(instruction.Argument2);
                    }
                }
            }

            return(result);
        }
예제 #6
0
        public override InOutData <Dictionary <string, LatticeValue> > Execute(ControlFlowGraph graph, bool useRenumbering = true)
        {
            var blocks    = graph.GetCurrentBasicBlocks();
            var variables = new HashSet <string>();

            foreach (var block in blocks)
            {
                foreach (var instr in block.GetInstructions())
                {
                    if (checkStr(instr.Result) && !variables.Contains(instr.Result))
                    {
                        variables.Add(instr.Result);
                    }

                    if (checkStr(instr.Argument1) && instr.Argument1 != "True" &&
                        instr.Argument1 != "False" && !int.TryParse(instr.Argument1, out var temp1) && !variables.Contains(instr.Argument1))
                    {
                        variables.Add(instr.Argument1);
                    }

                    if (checkStr(instr.Argument2) && instr.Argument2 != "True" && instr.Argument2 != "False" &&
                        !int.TryParse(instr.Argument2, out var temp2) && !variables.Contains(instr.Argument2))
                    {
                        variables.Add(instr.Argument2);
                    }
                }
            }
            var temp = new Dictionary <string, LatticeValue>();

            foreach (var elem in variables)
            {
                temp.Add(elem, new LatticeValue(LatticeTypeData.UNDEF));
            }

            Init             = temp;
            TransferFunction = Transfer;
            return(base.Execute(graph));
        }
예제 #7
0
        public INsOUTs ExecuteNonGeneric(ControlFlowGraph g)
        {
            var blocks = g.GetCurrentBasicBlocks();
            var INs    = new Dictionary <BasicBlock, Dictionary <string, LatticeValue> >();
            var OUTs   = new Dictionary <BasicBlock, Dictionary <string, LatticeValue> >();

            var variables = new HashSet <string>();

            foreach (var block in blocks)
            {
                foreach (var instr in block.GetInstructions())
                {
                    if (checkStr(instr.Result) && !variables.Contains(instr.Result))
                    {
                        variables.Add(instr.Result);
                    }

                    if (checkStr(instr.Argument1) && instr.Argument1 != "True" &&
                        instr.Argument1 != "False" && !int.TryParse(instr.Argument1, out var temp1) && !variables.Contains(instr.Argument1))
                    {
                        variables.Add(instr.Argument1);
                    }

                    if (checkStr(instr.Argument2) && instr.Argument2 != "True" && instr.Argument2 != "False" &&
                        !int.TryParse(instr.Argument2, out var temp2) && !variables.Contains(instr.Argument2))
                    {
                        variables.Add(instr.Argument2);
                    }
                }
            }
            var temp = new Dictionary <string, LatticeValue>();

            foreach (var elem in variables)
            {
                temp.Add(elem, new LatticeValue(LatticeTypeData.UNDEF));
            }

            foreach (var block in blocks)
            {
                INs.Add(block, temp.ToDictionary(entry => entry.Key, entry => entry.Value));
                OUTs.Add(block, temp.ToDictionary(entry => entry.Key, entry => entry.Value));
            }

            var Changed = true;

            while (Changed)
            {
                Changed = false;
                foreach (var block in blocks)
                {
                    var parents = g.GetParentsBasicBlocks(g.VertexOf(block)).Select(x => x.block);
                    INs[block] = parents.Select(x => OUTs[x])
                                 .Aggregate(temp.ToDictionary(entry => entry.Key, entry => entry.Value), (x, y) => Collect(x, y));
                    var newOut = Transfer(block, INs[block]);
                    if (OUTs[block].Where(entry => newOut[entry.Key] != entry.Value).Any())
                    {
                        Changed     = true;
                        OUTs[block] = newOut;
                    }
                }
            }

            return(new INsOUTs {
                IN = INs, OUT = OUTs
            });
        }