Example #1
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> >());
            }
        }
Example #2
0
        private static bool IsUsedInOtherBlocks(
            ControlFlowGraph graph,
            BasicBlock blockWithDefinition,
            Instruction definitionToCheck,
            Dictionary <BasicBlock, HashSet <string> > usedVars,
            InOutInfo info)
        {
            var queue = new Queue <BasicBlock>();

            queue.Enqueue(blockWithDefinition);

            while (queue.Count != 0)
            {
                var block = queue.Dequeue();
                foreach (var child in graph.GetChildrenBasicBlocks(graph.VertexOf(block)).Select(z => z.block))
                {
                    var isRewritten = !info[child].Out.Contains(definitionToCheck);
                    var isUsed      = usedVars[block].Contains(definitionToCheck.Result);

                    if (!isRewritten)
                    {
                        if (isUsed)
                        {
                            return(true);
                        }
                        else
                        {
                            queue.Enqueue(child);
                        }
                    }
                    else
                    {
                        if (!isUsed)
                        {
                            continue;
                        }
                        else
                        {
                            // we need to check instructions before definitionToCheck is rewritten
                            foreach (var instruction in child.GetInstructions())
                            {
                                if (instruction.Argument1 == definitionToCheck.Result ||
                                    instruction.Argument2 == definitionToCheck.Result)
                                {
                                    return(true);
                                }

                                if (instruction.Result == definitionToCheck.Result)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
Example #3
0
        /// <summary>
        /// Проверка цикла на естественность
        /// </summary>
        /// <param name="loop">Проверяемый цикл</param>
        /// <param name="cfg">Граф потока управления</param>
        /// <returns>
        /// Вернёт флаг, естественнен ли он
        /// </returns>
        private static bool IsNaturalLoop(IReadOnlyCollection <BasicBlock> loop, ControlFlowGraph cfg)
        {
            foreach (var bblock in loop.Skip(1))
            {
                var parents = cfg.GetParentsBasicBlocks(cfg.VertexOf(bblock));
                if (parents.Count > 1)
                {
                    foreach (var parent in parents.Select(x => x.block))
                    {
                        if (!loop.Contains(parent))
                        {
                            return(false);
                        }
                    }
                }
            }

            return(true);
        }